mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Merge m-c to autoland a=merge
MozReview-Commit-ID: L0rsjIzeVij --HG-- extra : rebase_source : 8b581702a4534fb9394f8d3f4e85f65d6f4ff293
This commit is contained in:
commit
54a256d920
@ -56,7 +56,7 @@ jobs:
|
||||
# Match buildbot starts for now
|
||||
date: [{hour: 15, minute: 0}]
|
||||
mozilla-central: [{hour: 10, minute: 0}]
|
||||
mozilla-aurora: [{hour: 7, minute: 45}] # Buildbot uses minute 40
|
||||
mozilla-aurora: [] # bug 1358976
|
||||
# No default
|
||||
|
||||
- name: nightly-mochitest-valgrind
|
||||
|
@ -1982,9 +1982,19 @@ DocAccessible::ContentRemoved(Accessible* aChild)
|
||||
"container", parent, "child", aChild, nullptr);
|
||||
#endif
|
||||
|
||||
// XXX: event coalescence may kill us
|
||||
RefPtr<Accessible> kungFuDeathGripChild(aChild);
|
||||
|
||||
TreeMutation mt(parent);
|
||||
mt.BeforeRemoval(aChild);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aChild->Parent(), "Unparented #1");
|
||||
|
||||
if (aChild->IsDefunct()) {
|
||||
MOZ_ASSERT_UNREACHABLE("Event coalescence killed the accessible");
|
||||
mt.Done();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(aChild->Parent(), "Alive but unparented #1");
|
||||
|
||||
if (aChild->IsRelocated()) {
|
||||
nsTArray<RefPtr<Accessible> >* owned = mARIAOwnsHash.Get(parent);
|
||||
|
@ -5,6 +5,7 @@ var tabs = gBrowser.tabs;
|
||||
|
||||
var rect = ele => ele.getBoundingClientRect();
|
||||
var width = ele => rect(ele).width;
|
||||
var height = ele => rect(ele).height;
|
||||
var left = ele => rect(ele).left;
|
||||
var right = ele => rect(ele).right;
|
||||
var isLeft = (ele, msg) => is(left(ele) + tabstrip._tabMarginLeft, left(scrollbox), msg);
|
||||
@ -14,6 +15,11 @@ var nextLeftElement = () => elementFromPoint(left(scrollbox) - 1);
|
||||
var nextRightElement = () => elementFromPoint(right(scrollbox) + 1);
|
||||
var firstScrollable = () => tabs[gBrowser._numPinnedTabs];
|
||||
|
||||
var clickCenter = (ele, opts) => {
|
||||
EventUtils.synthesizeMouse(ele, Math.ceil(width(ele) / 2),
|
||||
Math.ceil(height(ele) / 2), opts);
|
||||
}
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
waitForExplicitFinish();
|
||||
@ -60,7 +66,7 @@ function runOverflowTests(aEvent) {
|
||||
"(" + right(gBrowser.selectedTab) + " <= " + right(scrollbox) + ")");
|
||||
|
||||
element = nextLeftElement();
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {});
|
||||
clickCenter(upButton, {});
|
||||
isLeft(element, "Scrolled one tab to the left with a single click");
|
||||
|
||||
let elementPoint = left(scrollbox) - width(scrollbox);
|
||||
@ -68,10 +74,10 @@ function runOverflowTests(aEvent) {
|
||||
if (elementPoint == right(element)) {
|
||||
element = element.nextSibling;
|
||||
}
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 2});
|
||||
clickCenter(upButton, {clickCount: 2});
|
||||
isLeft(element, "Scrolled one page of tabs with a double click");
|
||||
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 3});
|
||||
clickCenter(upButton, {clickCount: 3});
|
||||
var firstScrollableLeft = left(firstScrollable());
|
||||
ok(left(scrollbox) <= firstScrollableLeft, "Scrolled to the start with a triple click " +
|
||||
"(" + left(scrollbox) + " <= " + firstScrollableLeft + ")");
|
||||
|
@ -57,8 +57,6 @@ var whitelist = new Set([
|
||||
{file: "chrome://global/locale/printjoboptions.dtd",
|
||||
platforms: ["macosx", "win"]},
|
||||
|
||||
{file: "chrome://weave/locale/errors.properties"},
|
||||
|
||||
// devtools/client/inspector/bin/dev-server.js
|
||||
{file: "chrome://devtools/content/inspector/markup/markup.xhtml",
|
||||
isFromDevTools: true},
|
||||
|
@ -176,102 +176,106 @@ const CustomizableWidgets = [
|
||||
tooltiptext: "history-panelmenu.tooltiptext2",
|
||||
defaultArea: CustomizableUI.AREA_PANEL,
|
||||
onViewShowing(aEvent) {
|
||||
// Populate our list of history
|
||||
const kMaxResults = 15;
|
||||
let doc = aEvent.target.ownerDocument;
|
||||
let win = doc.defaultView;
|
||||
aEvent.detail.addBlocker(new Promise((resolve, reject) => {
|
||||
// Populate our list of history
|
||||
const kMaxResults = 15;
|
||||
let doc = aEvent.target.ownerDocument;
|
||||
let win = doc.defaultView;
|
||||
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.excludeQueries = true;
|
||||
options.queryType = options.QUERY_TYPE_HISTORY;
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.maxResults = kMaxResults;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.excludeQueries = true;
|
||||
options.queryType = options.QUERY_TYPE_HISTORY;
|
||||
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
||||
options.maxResults = kMaxResults;
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
|
||||
let items = doc.getElementById("PanelUI-historyItems");
|
||||
// Clear previous history items.
|
||||
while (items.firstChild) {
|
||||
items.firstChild.remove();
|
||||
}
|
||||
let items = doc.getElementById("PanelUI-historyItems");
|
||||
// Clear previous history items.
|
||||
while (items.firstChild) {
|
||||
items.firstChild.remove();
|
||||
}
|
||||
|
||||
// Get all statically placed buttons to supply them with keyboard shortcuts.
|
||||
let staticButtons = items.parentNode.getElementsByTagNameNS(kNSXUL, "toolbarbutton");
|
||||
for (let i = 0, l = staticButtons.length; i < l; ++i)
|
||||
CustomizableUI.addShortcut(staticButtons[i]);
|
||||
// Get all statically placed buttons to supply them with keyboard shortcuts.
|
||||
let staticButtons = items.parentNode.getElementsByTagNameNS(kNSXUL, "toolbarbutton");
|
||||
for (let i = 0, l = staticButtons.length; i < l; ++i)
|
||||
CustomizableUI.addShortcut(staticButtons[i]);
|
||||
|
||||
PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.asyncExecuteLegacyQueries([query], 1, options, {
|
||||
handleResult(aResultSet) {
|
||||
let onItemCommand = function(aItemCommandEvent) {
|
||||
// Only handle the click event for middle clicks, we're using the command
|
||||
// event otherwise.
|
||||
if (aItemCommandEvent.type == "click" &&
|
||||
aItemCommandEvent.button != 1) {
|
||||
return;
|
||||
PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.asyncExecuteLegacyQueries([query], 1, options, {
|
||||
handleResult(aResultSet) {
|
||||
let onItemCommand = function(aItemCommandEvent) {
|
||||
// Only handle the click event for middle clicks, we're using the command
|
||||
// event otherwise.
|
||||
if (aItemCommandEvent.type == "click" &&
|
||||
aItemCommandEvent.button != 1) {
|
||||
return;
|
||||
}
|
||||
let item = aItemCommandEvent.target;
|
||||
win.openUILink(item.getAttribute("targetURI"), aItemCommandEvent);
|
||||
CustomizableUI.hidePanelForNode(item);
|
||||
};
|
||||
let fragment = doc.createDocumentFragment();
|
||||
let row;
|
||||
while ((row = aResultSet.getNextRow())) {
|
||||
let uri = row.getResultByIndex(1);
|
||||
let title = row.getResultByIndex(2);
|
||||
|
||||
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
item.setAttribute("label", title || uri);
|
||||
item.setAttribute("targetURI", uri);
|
||||
item.setAttribute("class", "subviewbutton");
|
||||
item.addEventListener("command", onItemCommand);
|
||||
item.addEventListener("click", onItemCommand);
|
||||
item.setAttribute("image", "page-icon:" + uri);
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
let item = aItemCommandEvent.target;
|
||||
win.openUILink(item.getAttribute("targetURI"), aItemCommandEvent);
|
||||
CustomizableUI.hidePanelForNode(item);
|
||||
};
|
||||
let fragment = doc.createDocumentFragment();
|
||||
let row;
|
||||
while ((row = aResultSet.getNextRow())) {
|
||||
let uri = row.getResultByIndex(1);
|
||||
let title = row.getResultByIndex(2);
|
||||
items.appendChild(fragment);
|
||||
},
|
||||
handleError(aError) {
|
||||
log.debug("History view tried to show but had an error: " + aError);
|
||||
reject();
|
||||
},
|
||||
handleCompletion(aReason) {
|
||||
log.debug("History view is being shown!");
|
||||
resolve();
|
||||
},
|
||||
});
|
||||
|
||||
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
item.setAttribute("label", title || uri);
|
||||
item.setAttribute("targetURI", uri);
|
||||
item.setAttribute("class", "subviewbutton");
|
||||
item.addEventListener("command", onItemCommand);
|
||||
item.addEventListener("click", onItemCommand);
|
||||
item.setAttribute("image", "page-icon:" + uri);
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
items.appendChild(fragment);
|
||||
},
|
||||
handleError(aError) {
|
||||
log.debug("History view tried to show but had an error: " + aError);
|
||||
},
|
||||
handleCompletion(aReason) {
|
||||
log.debug("History view is being shown!");
|
||||
},
|
||||
});
|
||||
let recentlyClosedTabs = doc.getElementById("PanelUI-recentlyClosedTabs");
|
||||
while (recentlyClosedTabs.firstChild) {
|
||||
recentlyClosedTabs.firstChild.remove();
|
||||
}
|
||||
|
||||
let recentlyClosedTabs = doc.getElementById("PanelUI-recentlyClosedTabs");
|
||||
while (recentlyClosedTabs.firstChild) {
|
||||
recentlyClosedTabs.firstChild.remove();
|
||||
}
|
||||
let recentlyClosedWindows = doc.getElementById("PanelUI-recentlyClosedWindows");
|
||||
while (recentlyClosedWindows.firstChild) {
|
||||
recentlyClosedWindows.firstChild.remove();
|
||||
}
|
||||
|
||||
let recentlyClosedWindows = doc.getElementById("PanelUI-recentlyClosedWindows");
|
||||
while (recentlyClosedWindows.firstChild) {
|
||||
recentlyClosedWindows.firstChild.remove();
|
||||
}
|
||||
let utils = RecentlyClosedTabsAndWindowsMenuUtils;
|
||||
let tabsFragment = utils.getTabsFragment(doc.defaultView, "toolbarbutton", true,
|
||||
"menuRestoreAllTabsSubview.label");
|
||||
let separator = doc.getElementById("PanelUI-recentlyClosedTabs-separator");
|
||||
let elementCount = tabsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
let element = tabsFragment.children[elementCount];
|
||||
CustomizableUI.addShortcut(element);
|
||||
element.classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedTabs.appendChild(tabsFragment);
|
||||
|
||||
let utils = RecentlyClosedTabsAndWindowsMenuUtils;
|
||||
let tabsFragment = utils.getTabsFragment(doc.defaultView, "toolbarbutton", true,
|
||||
"menuRestoreAllTabsSubview.label");
|
||||
let separator = doc.getElementById("PanelUI-recentlyClosedTabs-separator");
|
||||
let elementCount = tabsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
let element = tabsFragment.children[elementCount];
|
||||
CustomizableUI.addShortcut(element);
|
||||
element.classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedTabs.appendChild(tabsFragment);
|
||||
|
||||
let windowsFragment = utils.getWindowsFragment(doc.defaultView, "toolbarbutton", true,
|
||||
"menuRestoreAllWindowsSubview.label");
|
||||
separator = doc.getElementById("PanelUI-recentlyClosedWindows-separator");
|
||||
elementCount = windowsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
let element = windowsFragment.children[elementCount];
|
||||
CustomizableUI.addShortcut(element);
|
||||
element.classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedWindows.appendChild(windowsFragment);
|
||||
let windowsFragment = utils.getWindowsFragment(doc.defaultView, "toolbarbutton", true,
|
||||
"menuRestoreAllWindowsSubview.label");
|
||||
separator = doc.getElementById("PanelUI-recentlyClosedWindows-separator");
|
||||
elementCount = windowsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
let element = windowsFragment.children[elementCount];
|
||||
CustomizableUI.addShortcut(element);
|
||||
element.classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedWindows.appendChild(windowsFragment);
|
||||
}));
|
||||
},
|
||||
onCreated(aNode) {
|
||||
// Middle clicking recently closed items won't close the panel - cope:
|
||||
|
@ -2,6 +2,8 @@
|
||||
* This file contains tests for the Preferences search bar.
|
||||
*/
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
/**
|
||||
* Tests to see if search bar is being hidden when pref is turned off
|
||||
*/
|
||||
|
@ -19,7 +19,11 @@
|
||||
--backbutton-border-color: var(--urlbar-border-color-hover);
|
||||
--backbutton-background: rgba(255,255,255,.15);
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
--toolbarbutton-border-radius: 2px;
|
||||
%else
|
||||
--toolbarbutton-border-radius: 1px;
|
||||
%endif
|
||||
|
||||
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-vertical-inner-padding) - 1px);
|
||||
|
||||
@ -264,12 +268,24 @@ menuitem.bookmark-item {
|
||||
#main-window {
|
||||
--urlbar-border-color: ThreeDShadow;
|
||||
--urlbar-border-color-hover: var(--urlbar-border-color);
|
||||
--urlbar-background-color: moz-field;
|
||||
}
|
||||
|
||||
#navigator-toolbox:-moz-lwtheme {
|
||||
--urlbar-border-color: rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
|
||||
%include ../shared/location-search-bar.inc.css
|
||||
|
||||
#urlbar[focused="true"],
|
||||
.searchbar-textbox[focused="true"] {
|
||||
border-color: Highlight;
|
||||
}
|
||||
|
||||
%else
|
||||
|
||||
#urlbar,
|
||||
.searchbar-textbox {
|
||||
-moz-appearance: none;
|
||||
@ -299,6 +315,7 @@ menuitem.bookmark-item {
|
||||
.searchbar-textbox:-moz-lwtheme[focused=true] {
|
||||
background-color: white;
|
||||
}
|
||||
%endif
|
||||
|
||||
.urlbar-textbox-container {
|
||||
-moz-appearance: none;
|
||||
|
@ -24,7 +24,11 @@
|
||||
|
||||
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-vertical-inner-padding) + 1px);
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
--toolbarbutton-border-radius: 4px;
|
||||
%else
|
||||
--toolbarbutton-border-radius: 3px;
|
||||
%endif
|
||||
|
||||
--toolbarbutton-hover-background: hsla(0,0%,100%,.1) linear-gradient(hsla(0,0%,100%,.3), hsla(0,0%,100%,.1)) padding-box;
|
||||
--toolbarbutton-hover-bordercolor: hsla(0,0%,0%,.2);
|
||||
@ -515,6 +519,29 @@ toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-p
|
||||
|
||||
/* ::::: nav-bar-inner ::::: */
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
|
||||
#main-window {
|
||||
--urlbar-border-color: hsla(240, 5%, 5%, .25);
|
||||
--urlbar-border-color-hover: hsla(240, 5%, 5%, .35);
|
||||
--urlbar-background-color: -moz-field;
|
||||
}
|
||||
|
||||
%include ../shared/location-search-bar.inc.css
|
||||
|
||||
#urlbar[focused="true"],
|
||||
.searchbar-textbox[focused="true"] {
|
||||
border-color: -moz-mac-focusring;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
}
|
||||
|
||||
#urlbar,
|
||||
.searchbar-textbox {
|
||||
font: icon;
|
||||
}
|
||||
|
||||
%else
|
||||
|
||||
#urlbar,
|
||||
.searchbar-textbox {
|
||||
font: icon;
|
||||
@ -563,7 +590,6 @@ toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-p
|
||||
border-radius: var(--toolbarbutton-border-radius);
|
||||
}
|
||||
|
||||
%ifndef MOZ_PHOTON_THEME
|
||||
@conditionalForwardWithUrlbar@ > #urlbar {
|
||||
border-inline-start: none;
|
||||
margin-left: 0;
|
||||
|
30
browser/themes/shared/location-search-bar.inc.css
Normal file
30
browser/themes/shared/location-search-bar.inc.css
Normal file
@ -0,0 +1,30 @@
|
||||
/* 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/. */
|
||||
|
||||
#urlbar,
|
||||
.searchbar-textbox {
|
||||
-moz-appearance: none;
|
||||
background-clip: content-box;
|
||||
background-color: var(--urlbar-background-color);
|
||||
border: 1px solid var(--urlbar-border-color);
|
||||
border-radius: var(--toolbarbutton-border-radius);
|
||||
box-shadow: 0 1px 4px hsla(0, 0%, 0%, .05);
|
||||
padding: 0;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
#urlbar:-moz-lwtheme:not(:hover):not([focused="true"]),
|
||||
.searchbar-textbox:-moz-lwtheme:not(:hover):not([focused="true"]) {
|
||||
background-color: hsla(0, 100%, 100%, .8);
|
||||
}
|
||||
|
||||
#urlbar:hover,
|
||||
.searchbar-textbox:hover {
|
||||
border: 1px solid var(--urlbar-border-color-hover);
|
||||
box-shadow: 0 1px 6px hsla(0, 0%, 0%, .1), 0 0 1px 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
#urlbar-container {
|
||||
-moz-box-align: center;
|
||||
}
|
@ -19,7 +19,11 @@
|
||||
|
||||
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-vertical-inner-padding) - 1px);
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
--toolbarbutton-border-radius: 2px;
|
||||
%else
|
||||
--toolbarbutton-border-radius: 1px;
|
||||
%endif
|
||||
|
||||
--toolbarbutton-hover-background: rgba(0,0,0,.1);
|
||||
--toolbarbutton-hover-bordercolor: rgba(0,0,0,.2);
|
||||
@ -657,6 +661,25 @@ toolbar[brighttext] #close-button {
|
||||
--urlbar-border-color: var(--toolbarbutton-hover-bordercolor);
|
||||
}
|
||||
|
||||
%ifdef MOZ_PHOTON_THEME
|
||||
|
||||
@media (-moz-windows-default-theme) {
|
||||
#main-window:not(:-moz-lwtheme) {
|
||||
--urlbar-border-color: hsla(240, 5%, 5%, .25);
|
||||
--urlbar-border-color-hover: hsla(240, 5%, 5%, .35);
|
||||
--urlbar-background-color: -moz-field;
|
||||
}
|
||||
}
|
||||
|
||||
%include ../shared/location-search-bar.inc.css
|
||||
|
||||
#urlbar[focused="true"],
|
||||
.searchbar-textbox[focused="true"] {
|
||||
border-color: Highlight;
|
||||
}
|
||||
|
||||
%else
|
||||
|
||||
@media (-moz-windows-default-theme) {
|
||||
@media (-moz-os-version: windows-win7),
|
||||
(-moz-os-version: windows-win8) {
|
||||
@ -753,7 +776,6 @@ toolbar[brighttext] #close-button {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
%ifndef MOZ_PHOTON_THEME
|
||||
@conditionalForwardWithUrlbar@ > #urlbar {
|
||||
border-inline-start: none;
|
||||
padding-inline-start: 0;
|
||||
|
@ -10,7 +10,6 @@
|
||||
font-size: 12px;
|
||||
font-family: Lucida Grande, Tahoma, sans-serif;
|
||||
line-height: 15px;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
color: red;
|
||||
}
|
||||
|
@ -74,9 +74,8 @@ nsJSInspector::EnterNestedEventLoop(JS::Handle<JS::Value> requestor, uint32_t *o
|
||||
mozilla::dom::AutoNoJSAPI nojsapi;
|
||||
|
||||
uint32_t nestLevel = ++mNestedLoopLevel;
|
||||
while (NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) {
|
||||
if (!NS_ProcessNextEvent())
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
if (!SpinEventLoopUntil([&]() { return mNestedLoopLevel < nestLevel; })) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mNestedLoopLevel <= nestLevel,
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include "nsAttrValue.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsCanvasFrame.h"
|
||||
#include "nsCaret.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
@ -8127,17 +8128,19 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
}
|
||||
size_t length;
|
||||
int32_t stride;
|
||||
Shmem surfaceData;
|
||||
IShmemAllocator* allocator = aChild ? static_cast<IShmemAllocator*>(aChild)
|
||||
: static_cast<IShmemAllocator*>(aParent);
|
||||
GetSurfaceData(dataSurface, &length, &stride,
|
||||
allocator,
|
||||
&surfaceData);
|
||||
Maybe<Shmem> surfaceData = GetSurfaceData(dataSurface, &length, &stride,
|
||||
allocator);
|
||||
|
||||
if (surfaceData.isNothing()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = flavorStr;
|
||||
// Turn item->data() into an nsCString prior to accessing it.
|
||||
item->data() = surfaceData;
|
||||
item->data() = surfaceData.ref();
|
||||
|
||||
IPCDataTransferImage& imageDetails = item->imageDetails();
|
||||
mozilla::gfx::IntSize size = dataSurface->GetSize();
|
||||
@ -8287,7 +8290,7 @@ struct GetSurfaceDataRawBuffer
|
||||
// a shared memory buffer.
|
||||
struct GetSurfaceDataShmem
|
||||
{
|
||||
using ReturnType = Shmem;
|
||||
using ReturnType = Maybe<Shmem>;
|
||||
using BufferType = char*;
|
||||
|
||||
explicit GetSurfaceDataShmem(IShmemAllocator* aAllocator)
|
||||
@ -8296,17 +8299,18 @@ struct GetSurfaceDataShmem
|
||||
|
||||
ReturnType Allocate(size_t aSize)
|
||||
{
|
||||
Shmem returnValue;
|
||||
mAllocator->AllocShmem(aSize,
|
||||
SharedMemory::TYPE_BASIC,
|
||||
&returnValue);
|
||||
return returnValue;
|
||||
Shmem shmem;
|
||||
if (!mAllocator->AllocShmem(aSize, SharedMemory::TYPE_BASIC, &shmem)) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
return Some(shmem);
|
||||
}
|
||||
|
||||
static BufferType
|
||||
GetBuffer(const ReturnType& aReturnValue)
|
||||
{
|
||||
return aReturnValue.get<char>();
|
||||
return aReturnValue.isSome() ? aReturnValue.ref().get<char>() : nullptr;
|
||||
}
|
||||
|
||||
static ReturnType
|
||||
@ -8374,14 +8378,13 @@ nsContentUtils::GetSurfaceData(
|
||||
return GetSurfaceDataImpl(aSurface, aLength, aStride);
|
||||
}
|
||||
|
||||
void
|
||||
Maybe<Shmem>
|
||||
nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride,
|
||||
IShmemAllocator* aAllocator,
|
||||
Shmem *aOutShmem)
|
||||
IShmemAllocator* aAllocator)
|
||||
{
|
||||
*aOutShmem = GetSurfaceDataImpl(aSurface, aLength, aStride,
|
||||
GetSurfaceDataShmem(aAllocator));
|
||||
return GetSurfaceDataImpl(aSurface, aLength, aStride,
|
||||
GetSurfaceDataShmem(aAllocator));
|
||||
}
|
||||
|
||||
mozilla::Modifiers
|
||||
@ -10251,7 +10254,6 @@ nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
// XXXheycam This probably needs to find the nsCanvasFrame's NAC too.
|
||||
if (nsIPresShell* presShell = aDocument->GetShell()) {
|
||||
if (nsIFrame* scrollFrame = presShell->GetRootScrollFrame()) {
|
||||
nsIAnonymousContentCreator* creator = do_QueryFrame(scrollFrame);
|
||||
@ -10259,6 +10261,12 @@ nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
||||
"scroll frame should always implement nsIAnonymousContentCreator");
|
||||
creator->AppendAnonymousContentTo(aElements, 0);
|
||||
}
|
||||
|
||||
if (nsCanvasFrame* canvasFrame = presShell->GetCanvasFrame()) {
|
||||
if (Element* container = canvasFrame->GetCustomContentContainer()) {
|
||||
aElements.AppendElement(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
@ -2673,10 +2674,10 @@ public:
|
||||
* Get the pixel data from the given source surface and fill it in Shmem.
|
||||
* The length and stride will be assigned from the surface.
|
||||
*/
|
||||
static void GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride,
|
||||
mozilla::ipc::IShmemAllocator* aAlloc,
|
||||
mozilla::ipc::Shmem *aOutShmem);
|
||||
static mozilla::Maybe<mozilla::ipc::Shmem>
|
||||
GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride,
|
||||
mozilla::ipc::IShmemAllocator* aAlloc);
|
||||
|
||||
// Helpers shared by the implementations of nsContentUtils methods and
|
||||
// nsIDOMWindowUtils methods.
|
||||
|
@ -11669,9 +11669,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
|
||||
// script.
|
||||
RefPtr<nsGlobalWindow> outer = GetOuterWindowInternal();
|
||||
outer->EnterModalState();
|
||||
while (!monitor->IsDebuggerStartupComplete()) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return monitor->IsDebuggerStartupComplete(); });
|
||||
outer->LeaveModalState();
|
||||
return ContinueSlowScript;
|
||||
}
|
||||
|
9
dom/cache/Manager.cpp
vendored
9
dom/cache/Manager.cpp
vendored
@ -1423,11 +1423,10 @@ Manager::ShutdownAll()
|
||||
|
||||
Factory::ShutdownAll();
|
||||
|
||||
while (!Factory::IsShutdownAllComplete()) {
|
||||
if (!NS_ProcessNextEvent()) {
|
||||
NS_WARNING("Something bad happened!");
|
||||
break;
|
||||
}
|
||||
if (!mozilla::SpinEventLoopUntil([]() {
|
||||
return Factory::IsShutdownAllComplete();
|
||||
})) {
|
||||
NS_WARNING("Something bad happened!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4790,12 +4790,7 @@ BlobParent::RecvBlobStreamSync(const uint64_t& aStart,
|
||||
|
||||
// The actor is alive and will be doing asynchronous work to load the stream.
|
||||
// Spin a nested loop here while we wait for it.
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread);
|
||||
|
||||
while (!finished) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return finished; }));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -947,12 +947,7 @@ FileHandleThreadPool::Shutdown()
|
||||
return;
|
||||
}
|
||||
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread);
|
||||
|
||||
while (!mShutdownComplete) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return mShutdownComplete; }));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -12532,12 +12532,7 @@ ConnectionPool::Shutdown()
|
||||
return;
|
||||
}
|
||||
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread);
|
||||
|
||||
while (!mShutdownComplete) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return mShutdownComplete; }));
|
||||
}
|
||||
|
||||
void
|
||||
@ -13494,7 +13489,7 @@ ThreadRunnable::Run()
|
||||
"ConnectionPool::ThreadRunnable::Run",
|
||||
js::ProfileEntry::Category::STORAGE);
|
||||
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
DebugOnly<nsIThread*> currentThread = NS_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -13516,8 +13511,10 @@ ThreadRunnable::Run()
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
while (mContinueRunning) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||
DebugOnly<bool> b = SpinEventLoopUntil([&]() -> bool {
|
||||
if (!mContinueRunning) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (kDEBUGTransactionThreadSleepMS) {
|
||||
@ -13526,7 +13523,14 @@ ThreadRunnable::Run()
|
||||
PR_SUCCESS);
|
||||
}
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
// MSVC can't stringify lambdas, so we have to separate the expression
|
||||
// generating the value from the assert itself.
|
||||
#if DEBUG
|
||||
MOZ_ALWAYS_TRUE(b);
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2704,9 +2704,7 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
// Wait for shutdown to complete, so that we receive any shutdown
|
||||
// data (e.g. telemetry) from the child before we quit.
|
||||
// This loop terminate prematurely based on mForceKillTimer.
|
||||
while (mIPCOpen && !mCalledKillHard) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });
|
||||
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
||||
}
|
||||
|
||||
|
@ -1641,8 +1641,7 @@ MediaDecoder::IsWebMEnabled()
|
||||
bool
|
||||
MediaDecoder::IsAndroidMediaPluginEnabled()
|
||||
{
|
||||
return AndroidBridge::Bridge()
|
||||
&& AndroidBridge::Bridge()->GetAPIVersion() < 16
|
||||
return jni::GetAPIVersion() < 16
|
||||
&& Preferences::GetBool("media.plugins.enabled");
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define MEDIA_PREFS_H
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
@ -201,8 +201,7 @@ private:
|
||||
static int32_t MediaDecoderLimitDefault()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (AndroidBridge::Bridge() &&
|
||||
AndroidBridge::Bridge()->GetAPIVersion() < 18) {
|
||||
if (jni::GetAPIVersion() < 18) {
|
||||
// Older Android versions have broken support for multiple simultaneous
|
||||
// decoders, see bug 1278574.
|
||||
return 1;
|
||||
|
@ -299,10 +299,7 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject,
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
// Wait for UnloadPlugins() to do sync shutdown...
|
||||
while (mWaitingForPluginsSyncShutdown) {
|
||||
NS_ProcessNextEvent(NS_GetCurrentThread(), true);
|
||||
}
|
||||
|
||||
SpinEventLoopUntil([&]() { return !mWaitingForPluginsSyncShutdown; });
|
||||
} else {
|
||||
// GMP thread has already shutdown.
|
||||
MOZ_ASSERT(mPlugins.IsEmpty());
|
||||
|
@ -20,9 +20,7 @@ public:
|
||||
void AwaitFinished()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
while (!mFinished) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
mozilla::SpinEventLoopUntil([&]() { return mFinished; });
|
||||
mFinished = false;
|
||||
}
|
||||
|
||||
|
@ -1158,9 +1158,7 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||
}
|
||||
|
||||
void AwaitFinished() {
|
||||
while (!mFinished) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
mozilla::SpinEventLoopUntil([&]() -> bool { return mFinished; });
|
||||
mFinished = false;
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,7 @@ public:
|
||||
[&]() { done = true; });
|
||||
|
||||
// Wait until benchmark completes.
|
||||
while (!done) {
|
||||
NS_ProcessNextEvent();
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return done; });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AndroidDecoderModule.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaPrefs.h"
|
||||
#include "OpusDecoder.h"
|
||||
@ -128,8 +127,7 @@ AndroidDecoderModule::SupportsMimeType(
|
||||
const nsACString& aMimeType,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const
|
||||
{
|
||||
if (!AndroidBridge::Bridge() ||
|
||||
AndroidBridge::Bridge()->GetAPIVersion() < 16) {
|
||||
if (jni::GetAPIVersion() < 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidDecoderModule.h"
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "JavaCallbacksSupport.h"
|
||||
#include "SimpleMap.h"
|
||||
#include "GLImages.h"
|
||||
@ -134,7 +133,7 @@ public:
|
||||
|
||||
if (size > 0) {
|
||||
RefPtr<layers::Image> img = new SurfaceTextureImage(
|
||||
mDecoder->mSurfaceTexture.get(), inputInfo.mImageSize,
|
||||
mDecoder->mSurfaceHandle, inputInfo.mImageSize, false /* NOT continuous */,
|
||||
gl::OriginPos::BottomLeft);
|
||||
|
||||
RefPtr<VideoData> v = VideoData::CreateFromImage(
|
||||
@ -177,18 +176,12 @@ public:
|
||||
|
||||
RefPtr<InitPromise> Init() override
|
||||
{
|
||||
mSurfaceTexture = AndroidSurfaceTexture::Create();
|
||||
if (!mSurfaceTexture) {
|
||||
NS_WARNING("Failed to create SurfaceTexture for video decode\n");
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||
__func__);
|
||||
GeckoSurface::LocalRef surf = GeckoSurface::LocalRef(SurfaceAllocator::AcquireSurface(mConfig.mImage.width, mConfig.mImage.height, false));
|
||||
if (!surf) {
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||
}
|
||||
|
||||
if (!jni::IsFennec()) {
|
||||
NS_WARNING("Remote decoding not supported in non-Fennec environment\n");
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||
__func__);
|
||||
}
|
||||
mSurfaceHandle = surf->GetHandle();
|
||||
|
||||
// Register native methods.
|
||||
JavaCallbacksSupport::Init();
|
||||
@ -199,7 +192,7 @@ public:
|
||||
|
||||
mJavaDecoder = CodecProxy::Create(false, // false indicates to create a decoder and true denotes encoder
|
||||
mFormat,
|
||||
mSurfaceTexture->JavaSurface(),
|
||||
surf,
|
||||
mJavaCallbacks,
|
||||
mDrmStubId);
|
||||
if (mJavaDecoder == nullptr) {
|
||||
@ -239,7 +232,7 @@ public:
|
||||
private:
|
||||
layers::ImageContainer* mImageContainer;
|
||||
const VideoInfo mConfig;
|
||||
RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
|
||||
AndroidSurfaceTextureHandle mSurfaceHandle;
|
||||
SimpleMap<InputInfo> mInputInfos;
|
||||
bool mIsCodecSupportAdaptivePlayback = false;
|
||||
};
|
||||
@ -411,7 +404,6 @@ RemoteDataDecoder::CreateVideoDecoder(const CreateDecoderParams& aParams,
|
||||
const nsString& aDrmStubId,
|
||||
CDMProxy* aProxy)
|
||||
{
|
||||
|
||||
const VideoInfo& config = aParams.VideoConfig();
|
||||
MediaFormat::LocalRef format;
|
||||
NS_ENSURE_SUCCESS(
|
||||
|
@ -122,11 +122,8 @@ UDPSocketChild::CreatePBackgroundSpinUntilDone()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsIThread* thread = NS_GetCurrentThread();
|
||||
while (!done) {
|
||||
if (NS_WARN_IF(!NS_ProcessNextEvent(thread, true /* aMayWait */))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!SpinEventLoopUntil([&done]() { return done; })) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!BackgroundChild::GetForCurrentThread())) {
|
||||
|
@ -58,6 +58,8 @@ using namespace mozilla::dom;
|
||||
#include "TexturePoolOGL.h"
|
||||
#include "SurfaceTypes.h"
|
||||
#include "EGLUtils.h"
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "GeneratedJNINatives.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
@ -106,7 +108,7 @@ static bool EnsureGLContext()
|
||||
|
||||
static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
|
||||
|
||||
#endif
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::plugins::parent;
|
||||
@ -202,14 +204,12 @@ nsNPAPIPluginInstance::Destroy()
|
||||
mAudioChannelAgent = nullptr;
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
if (mContentSurface)
|
||||
mContentSurface->SetFrameAvailableCallback(nullptr);
|
||||
|
||||
mContentSurface = nullptr;
|
||||
if (mContentSurface) {
|
||||
java::SurfaceAllocator::DisposeSurface(mContentSurface);
|
||||
}
|
||||
|
||||
std::map<void*, VideoInfo*>::iterator it;
|
||||
for (it = mVideos.begin(); it != mVideos.end(); it++) {
|
||||
it->second->mSurfaceTexture->SetFrameAvailableCallback(nullptr);
|
||||
delete it->second;
|
||||
}
|
||||
mVideos.clear();
|
||||
@ -858,24 +858,50 @@ GLContext* nsNPAPIPluginInstance::GLContext()
|
||||
return sPluginContext;
|
||||
}
|
||||
|
||||
already_AddRefed<AndroidSurfaceTexture> nsNPAPIPluginInstance::CreateSurfaceTexture()
|
||||
class PluginTextureListener
|
||||
: public java::SurfaceTextureListener::Natives<PluginTextureListener>
|
||||
{
|
||||
if (!EnsureGLContext())
|
||||
return nullptr;
|
||||
using Base = java::SurfaceTextureListener::Natives<PluginTextureListener>;
|
||||
|
||||
GLuint texture = TexturePoolOGL::AcquireTexture();
|
||||
if (!texture)
|
||||
return nullptr;
|
||||
const nsCOMPtr<nsIRunnable> mCallback;
|
||||
public:
|
||||
using Base::AttachNative;
|
||||
using Base::DisposeNative;
|
||||
|
||||
RefPtr<AndroidSurfaceTexture> surface = AndroidSurfaceTexture::Create(TexturePoolOGL::GetGLContext(),
|
||||
texture);
|
||||
if (!surface) {
|
||||
PluginTextureListener(nsIRunnable* aCallback) : mCallback(aCallback) {}
|
||||
|
||||
void OnFrameAvailable()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
mCallback->Run();
|
||||
return;
|
||||
}
|
||||
NS_DispatchToMainThread(mCallback);
|
||||
}
|
||||
};
|
||||
|
||||
java::GeckoSurface::LocalRef nsNPAPIPluginInstance::CreateSurface()
|
||||
{
|
||||
java::GeckoSurface::LocalRef surf = java::SurfaceAllocator::AcquireSurface(0, 0, false);
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> frameCallback = NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
|
||||
surface->SetFrameAvailableCallback(frameCallback);
|
||||
return surface.forget();
|
||||
|
||||
java::SurfaceTextureListener::LocalRef listener = java::SurfaceTextureListener::New();
|
||||
|
||||
PluginTextureListener::AttachNative(listener, MakeUnique<PluginTextureListener>(frameCallback.get()));
|
||||
|
||||
java::GeckoSurfaceTexture::LocalRef gst = java::GeckoSurfaceTexture::Lookup(surf->GetHandle());
|
||||
if (!gst) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& st = java::sdk::SurfaceTexture::Ref::From(gst);
|
||||
st->SetOnFrameAvailableListener(listener);
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
|
||||
@ -886,35 +912,29 @@ void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
|
||||
|
||||
void* nsNPAPIPluginInstance::AcquireContentWindow()
|
||||
{
|
||||
if (!mContentSurface) {
|
||||
mContentSurface = CreateSurfaceTexture();
|
||||
|
||||
if (!mContentWindow.NativeWindow()) {
|
||||
mContentSurface = CreateSurface();
|
||||
if (!mContentSurface)
|
||||
return nullptr;
|
||||
|
||||
mContentWindow = AndroidNativeWindow(mContentSurface);
|
||||
}
|
||||
|
||||
return mContentSurface->NativeWindow();
|
||||
return mContentWindow.NativeWindow();
|
||||
}
|
||||
|
||||
AndroidSurfaceTexture*
|
||||
nsNPAPIPluginInstance::AsSurfaceTexture()
|
||||
java::GeckoSurface::Param
|
||||
nsNPAPIPluginInstance::AsSurface()
|
||||
{
|
||||
if (!mContentSurface)
|
||||
return nullptr;
|
||||
|
||||
return mContentSurface;
|
||||
}
|
||||
|
||||
void* nsNPAPIPluginInstance::AcquireVideoWindow()
|
||||
{
|
||||
RefPtr<AndroidSurfaceTexture> surface = CreateSurfaceTexture();
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
java::GeckoSurface::LocalRef surface = CreateSurface();
|
||||
VideoInfo* info = new VideoInfo(surface);
|
||||
|
||||
void* window = info->mSurfaceTexture->NativeWindow();
|
||||
void* window = info->mNativeWindow.NativeWindow();
|
||||
mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
|
||||
|
||||
return window;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "nsIRunnable.h"
|
||||
#include "GLContextTypes.h"
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "AndroidNativeWindow.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include <map>
|
||||
class PluginEventRunnable;
|
||||
@ -215,22 +215,24 @@ public:
|
||||
// For ANPNativeWindow
|
||||
void* AcquireContentWindow();
|
||||
|
||||
mozilla::gl::AndroidSurfaceTexture* AsSurfaceTexture();
|
||||
mozilla::java::GeckoSurface::Param AsSurface();
|
||||
|
||||
// For ANPVideo
|
||||
class VideoInfo {
|
||||
public:
|
||||
VideoInfo(mozilla::gl::AndroidSurfaceTexture* aSurfaceTexture) :
|
||||
mSurfaceTexture(aSurfaceTexture)
|
||||
VideoInfo(mozilla::java::GeckoSurface::Param aSurface)
|
||||
: mSurface(aSurface)
|
||||
, mNativeWindow(aSurface)
|
||||
{
|
||||
}
|
||||
|
||||
~VideoInfo()
|
||||
{
|
||||
mSurfaceTexture = nullptr;
|
||||
mozilla::java::SurfaceAllocator::DisposeSurface(mSurface);
|
||||
}
|
||||
|
||||
RefPtr<mozilla::gl::AndroidSurfaceTexture> mSurfaceTexture;
|
||||
mozilla::java::GeckoSurface::GlobalRef mSurface;
|
||||
mozilla::gl::AndroidNativeWindow mNativeWindow;
|
||||
gfxRect mDimensions;
|
||||
};
|
||||
|
||||
@ -359,7 +361,8 @@ protected:
|
||||
bool mFullScreen;
|
||||
mozilla::gl::OriginPos mOriginPos;
|
||||
|
||||
RefPtr<mozilla::gl::AndroidSurfaceTexture> mContentSurface;
|
||||
mozilla::java::GeckoSurface::GlobalRef mContentSurface;
|
||||
mozilla::gl::AndroidNativeWindow mContentWindow;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
@ -409,8 +412,7 @@ private:
|
||||
mozilla::TimeStamp mStopTime;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
already_AddRefed<mozilla::gl::AndroidSurfaceTexture> CreateSurfaceTexture();
|
||||
|
||||
mozilla::java::GeckoSurface::LocalRef CreateSurface();
|
||||
std::map<void*, VideoInfo*> mVideos;
|
||||
bool mOnScreen;
|
||||
|
||||
|
@ -1727,9 +1727,7 @@ nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
|
||||
rv = library->NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback>(do_QueryInterface(closure)));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Spin the event loop while we wait for the async call to GetSitesWithData
|
||||
while (closure->keepWaiting) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return !closure->keepWaiting; });
|
||||
*result = closure->result;
|
||||
return closure->retVal;
|
||||
}
|
||||
|
@ -165,22 +165,23 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
static void
|
||||
AttachToContainerAsSurfaceTexture(ImageContainer* container,
|
||||
nsNPAPIPluginInstance* instance,
|
||||
const LayoutDeviceRect& rect,
|
||||
RefPtr<Image>* out_image)
|
||||
AttachToContainerAsSurface(ImageContainer* container,
|
||||
nsNPAPIPluginInstance* instance,
|
||||
const LayoutDeviceRect& rect,
|
||||
RefPtr<Image>* out_image)
|
||||
{
|
||||
MOZ_ASSERT(out_image);
|
||||
MOZ_ASSERT(!*out_image);
|
||||
|
||||
mozilla::gl::AndroidSurfaceTexture* surfTex = instance->AsSurfaceTexture();
|
||||
if (!surfTex) {
|
||||
java::GeckoSurface::LocalRef surface = instance->AsSurface();
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Image> img = new SurfaceTextureImage(
|
||||
surfTex,
|
||||
surface->GetHandle(),
|
||||
gfx::IntSize::Truncate(rect.width, rect.height),
|
||||
true, // continuously update without a transaction
|
||||
instance->OriginPos());
|
||||
*out_image = img;
|
||||
}
|
||||
@ -223,7 +224,7 @@ nsPluginInstanceOwner::GetImageContainer()
|
||||
if (r.width && r.height) {
|
||||
// Try to get it as an EGLImage first.
|
||||
RefPtr<Image> img;
|
||||
AttachToContainerAsSurfaceTexture(container, mInstance, r, &img);
|
||||
AttachToContainerAsSurface(container, mInstance, r, &img);
|
||||
|
||||
if (img) {
|
||||
container->SetCurrentImageInTransaction(img);
|
||||
@ -1585,8 +1586,9 @@ nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInf
|
||||
|
||||
if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) {
|
||||
RefPtr<Image> img = new SurfaceTextureImage(
|
||||
aVideoInfo->mSurfaceTexture,
|
||||
aVideoInfo->mSurface->GetHandle(),
|
||||
gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
|
||||
true, /* continuous */
|
||||
gl::OriginPos::BottomLeft);
|
||||
container->SetCurrentImageInTransaction(img);
|
||||
}
|
||||
|
@ -2858,12 +2858,7 @@ ShutdownObserver::Observe(nsISupports* aSubject,
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
mBackgroundThread->Dispatch(shutdownRunnable, NS_DISPATCH_NORMAL));
|
||||
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread);
|
||||
|
||||
while (!done) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return done; }));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -103,19 +103,8 @@ function testScript(script) {
|
||||
}
|
||||
|
||||
navigator.serviceWorker.register("worker_wrapper.js", {scope: "."})
|
||||
.then(function(registration) {
|
||||
if (registration.installing) {
|
||||
var done = false;
|
||||
registration.installing.onstatechange = function() {
|
||||
if (!done) {
|
||||
done = true;
|
||||
setupSW(registration);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
setupSW(registration);
|
||||
}
|
||||
});
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then(setupSW);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,11 @@ function testScript(script) {
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true]]
|
||||
}, function() {
|
||||
navigator.serviceWorker.ready.then(setupSW);
|
||||
var scriptURL = location.href.includes("sw_empty_reroute.html")
|
||||
? "empty.js" : "reroute.js";
|
||||
navigator.serviceWorker.register(scriptURL, {scope: "/"});
|
||||
navigator.serviceWorker.register(scriptURL, {scope: "/"})
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then(setupSW);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_basic_http.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_basic_http.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_basic.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_basic.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_cors.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_fetch_cors.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_formdataparsing.js");
|
||||
|
@ -8,6 +8,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_headers_common.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_request.js");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="utils.js"> </script>
|
||||
<script type="text/javascript" src="sw_reroute.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_response.js");
|
||||
|
@ -35,3 +35,17 @@ function readAsArrayBuffer(blob) {
|
||||
}
|
||||
}
|
||||
|
||||
function waitForState(worker, state, context) {
|
||||
return new Promise(resolve => {
|
||||
if (worker.state === state) {
|
||||
resolve(context);
|
||||
return;
|
||||
}
|
||||
worker.addEventListener('statechange', function onStateChange() {
|
||||
if (worker.state === state) {
|
||||
worker.removeEventListener('statechange', onStateChange);
|
||||
resolve(context);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -902,7 +902,9 @@ private:
|
||||
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = mWorkerPrivate->GetLoadGroup();
|
||||
MOZ_DIAGNOSTIC_ASSERT(principal);
|
||||
MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(loadGroup, principal));
|
||||
|
||||
NS_ENSURE_TRUE(NS_LoadGroupMatchesPrincipal(loadGroup, principal),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
// Figure out our base URI.
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI(mIsMainScript, mWorkerPrivate);
|
||||
|
@ -989,13 +989,7 @@ ServiceWorkerRegistrar::ProfileStopped()
|
||||
|
||||
child->SendShutdownServiceWorkerRegistrar();
|
||||
|
||||
nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
|
||||
while (true) {
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(thread));
|
||||
if (completed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return completed; }));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4798,6 +4798,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
||||
|
||||
loadInfo.mBaseURI = document->GetDocBaseURI();
|
||||
loadInfo.mLoadGroup = document->GetDocumentLoadGroup();
|
||||
NS_ENSURE_TRUE(loadInfo.mLoadGroup, NS_ERROR_FAILURE);
|
||||
|
||||
// Use the document's NodePrincipal as our principal if we're not being
|
||||
// called from chrome.
|
||||
@ -4833,6 +4834,10 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(NS_LoadGroupMatchesPrincipal(loadInfo.mLoadGroup,
|
||||
loadInfo.mPrincipal),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -4951,6 +4956,9 @@ WorkerPrivate::OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo)
|
||||
MOZ_ALWAYS_SUCCEEDS(rv);
|
||||
|
||||
aLoadInfo.mLoadGroup = loadGroup.forget();
|
||||
|
||||
MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(aLoadInfo.mLoadGroup,
|
||||
aLoadInfo.mPrincipal));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,6 +215,7 @@ support-files =
|
||||
nofetch_handler_worker.js
|
||||
service_worker.js
|
||||
service_worker_client.html
|
||||
utils.js
|
||||
|
||||
[test_bug1151916.html]
|
||||
[test_bug1240436.html]
|
||||
|
@ -23,6 +23,7 @@
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
add_task(function setupPrefs() {
|
||||
return SpecialPowers.pushPrefEnv({"set": [
|
||||
@ -47,13 +48,7 @@ add_task(function* async_wait_until() {
|
||||
"async_waituntil_worker.js", { scope: "./"} )
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return new Promise(function(resolve) {
|
||||
worker.addEventListener('statechange', function() {
|
||||
if (worker.state === 'activated') {
|
||||
resolve(registration);
|
||||
}
|
||||
});
|
||||
});
|
||||
return waitForState(worker, 'activated', registration);
|
||||
});
|
||||
|
||||
// The service worker will claim us when it becomes active.
|
||||
|
@ -17,6 +17,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var worker;
|
||||
@ -24,7 +25,10 @@
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("client_focus_worker.js",
|
||||
{ scope: "./sw_clients/focus_stealing_client.html" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr;
|
||||
returun waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var content;
|
||||
@ -22,9 +23,8 @@
|
||||
function simpleRegister() {
|
||||
// We use the control scope for the less specific registration. The window will register a worker on controller/
|
||||
return navigator.serviceWorker.register("worker.js", { scope: "./control" })
|
||||
.then(function(reg) {
|
||||
registration = reg;
|
||||
});;
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then(swr => registration = swr);
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,18 +13,17 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
var registration;
|
||||
function simpleRegister() {
|
||||
var p = navigator.serviceWorker.register("fetch_event_worker.js", { scope: "./fetch" });
|
||||
return p.then(function(swr) {
|
||||
registration = swr;
|
||||
return new Promise(function(resolve) {
|
||||
swr.installing.onstatechange = resolve;
|
||||
return navigator.serviceWorker.register("fetch_event_worker.js", { scope: "./fetch" })
|
||||
.then(swr => {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var scope = './file_blob_response/';
|
||||
@ -21,14 +22,7 @@
|
||||
{ scope: scope })
|
||||
.then(function(swr) {
|
||||
registration = swr;
|
||||
return new Promise(function(resolve) {
|
||||
registration.installing.onstatechange = function(evt) {
|
||||
if (evt.target.state === 'activated') {
|
||||
evt.target.onstate = null;
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
return new waitForState(swr.installing, 'activated');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,17 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var iframe;
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("empty.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr
|
||||
return waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,12 +13,16 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("gzip_redirect_worker.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -11,11 +11,13 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="content"></div>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("importscript_worker.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then(swr => registration = swr);
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
// match_all_worker will call matchAll until the worker shuts down.
|
||||
// Test passes if the browser doesn't crash on leaked promise objects.
|
||||
@ -23,7 +24,10 @@
|
||||
function simpleRegister() {
|
||||
return navigator.serviceWorker.register("match_all_worker.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function closeAndUnregister() {
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var client_iframes = [];
|
||||
var registration;
|
||||
@ -21,6 +22,8 @@
|
||||
return navigator.serviceWorker.register("match_all_advanced_worker.js",
|
||||
{ scope: "./sw_clients/" }).then(function(swr) {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated');
|
||||
}).then(_ => {
|
||||
window.onmessage = function (e) {
|
||||
if (e.data === "READY") {
|
||||
ok(registration.active, "Worker is active.");
|
||||
|
@ -13,13 +13,17 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var clientURL = "match_all_client/match_all_client_id.html";
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("match_all_client_id_worker.js",
|
||||
{ scope: "./match_all_client/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -13,13 +13,17 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var clientURL = "match_all_clients/match_all_controlled.html";
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("match_all_properties_worker.js",
|
||||
{ scope: "./match_all_clients/" })
|
||||
.then((swr) => registration = swr);
|
||||
.then((swr) => {
|
||||
registration = swr;
|
||||
return waitForState(swr.installing, 'activated', swr);
|
||||
});
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
add_task(function setupPrefs() {
|
||||
@ -44,16 +45,7 @@ function create_iframe(url) {
|
||||
add_task(function* test_nofetch_worker() {
|
||||
let registration = yield navigator.serviceWorker.register(
|
||||
"nofetch_handler_worker.js", { scope: "./nofetch_handler_worker/"} )
|
||||
.then(function(registration) {
|
||||
var worker = registration.installing;
|
||||
return new Promise(function(resolve) {
|
||||
worker.addEventListener('statechange', function() {
|
||||
if (worker.state === 'activated') {
|
||||
resolve(registration);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr));
|
||||
|
||||
let iframe = yield create_iframe("./nofetch_handler_worker/doesnt_exist.html");
|
||||
ok(!iframe.contentDocument.body.innerHTML.includes("intercepted"), "Request was not intercepted.");
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
@ -21,9 +22,7 @@
|
||||
var p = navigator.serviceWorker.register("./fetch/plugin/worker.js", { scope: "./fetch/plugin/" });
|
||||
return p.then(function(swr) {
|
||||
registration = swr;
|
||||
return new Promise(function(resolve) {
|
||||
swr.installing.onstatechange = resolve;
|
||||
});
|
||||
return waitForState(swr.installing, 'activated');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1172870
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script src="utils.js"></script>
|
||||
<script type="text/javascript">
|
||||
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show and click events.");
|
||||
|
||||
@ -27,17 +28,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1172870
|
||||
.then(function(swr) {
|
||||
ok(swr, "Registration successful");
|
||||
ctx.registration = swr;
|
||||
return ctx;
|
||||
return waitForState(swr.installing, 'activated', ctx);
|
||||
});
|
||||
}
|
||||
|
||||
function waitForActiveServiceWorker(ctx) {
|
||||
return navigator.serviceWorker.ready.then(function(result) {
|
||||
ok(ctx.registration.active, "Service Worker is active");
|
||||
return ctx;
|
||||
});
|
||||
}
|
||||
|
||||
function setupMessageHandler(ctx) {
|
||||
return new Promise(function(res, rej) {
|
||||
navigator.serviceWorker.onmessage = function(event) {
|
||||
@ -87,7 +81,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1172870
|
||||
|
||||
function runTest() {
|
||||
setup({})
|
||||
.then(waitForActiveServiceWorker)
|
||||
// Permission to allow popups persists for some time after a notification
|
||||
// click event, so the order here is important.
|
||||
.then(testPopupNotAllowed)
|
||||
|
@ -13,12 +13,14 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var magic_value = "MAGIC_VALUE_123";
|
||||
var registration;
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("message_posting_worker.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then((swr) => registration = swr);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var base = ["string", true, 42];
|
||||
@ -49,6 +50,7 @@
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("message_posting_worker.js",
|
||||
{ scope: "./sw_clients/" })
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr))
|
||||
.then((swr) => registration = swr);
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,14 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var regisration;
|
||||
function simpleRegister() {
|
||||
return navigator.serviceWorker.register("service_worker.js", {
|
||||
scope: 'service_worker_client.html'
|
||||
});
|
||||
}).then(swr => waitForState(swr.installing, 'activated', swr));
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
|
@ -11,10 +11,12 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function simpleRegister() {
|
||||
return navigator.serviceWorker.register("worker_update.js", { scope: "workerUpdate/" });
|
||||
return navigator.serviceWorker.register("worker_update.js", { scope: "workerUpdate/" })
|
||||
.then(swr => waitForState(swr.installing, 'activated', swr));
|
||||
}
|
||||
|
||||
var registration;
|
||||
|
@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var worker;
|
||||
@ -24,18 +25,7 @@
|
||||
registration = swr;
|
||||
|
||||
// Ensure the registration is active before continuing
|
||||
var worker = registration.installing;
|
||||
return new Promise((resolve) => {
|
||||
if (worker.state === 'activated') {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
worker.addEventListener('statechange', () => {
|
||||
if (worker.state === 'activated') {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
return waitForState(swr.installing, 'activated');
|
||||
});
|
||||
}
|
||||
|
||||
|
14
dom/workers/test/serviceworkers/utils.js
Normal file
14
dom/workers/test/serviceworkers/utils.js
Normal file
@ -0,0 +1,14 @@
|
||||
function waitForState(worker, state, context) {
|
||||
return new Promise(resolve => {
|
||||
if (worker.state === state) {
|
||||
resolve(context);
|
||||
return;
|
||||
}
|
||||
worker.addEventListener('statechange', function onStateChange() {
|
||||
if (worker.state === state) {
|
||||
worker.removeEventListener('statechange', onStateChange);
|
||||
resolve(context);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
@ -3000,12 +3000,8 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoSyncOperation sync(mSuspendedDoc);
|
||||
nsIThread *thread = NS_GetCurrentThread();
|
||||
while (mFlagSyncLooping) {
|
||||
if (!NS_ProcessNextEvent(thread)) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Time expired... We should throw.
|
||||
|
@ -462,14 +462,9 @@ XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType,
|
||||
}
|
||||
|
||||
if (!mAsync) {
|
||||
nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
|
||||
|
||||
nsAutoSyncOperation sync(this);
|
||||
mLoopingForSyncLoad = true;
|
||||
while (mLoopingForSyncLoad) {
|
||||
if (!NS_ProcessNextEvent(thread))
|
||||
break;
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return !mLoopingForSyncLoad; });
|
||||
|
||||
// We set return to true unless there was a parsing error
|
||||
Element* rootElement = GetRootElement();
|
||||
|
@ -310,12 +310,6 @@ nsresult nsAutoConfig::downloadAutoConfig()
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
|
||||
// Getting the current thread. If we start an AsyncOpen, the thread
|
||||
// needs to wait before the reading of autoconfig is done
|
||||
|
||||
nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
|
||||
NS_ENSURE_STATE(thread);
|
||||
|
||||
/* process events until we're finished. AutoConfig.jsc reading needs
|
||||
to be finished before the browser starts loading up
|
||||
We are waiting for the mLoaded which will be set through
|
||||
@ -323,9 +317,10 @@ nsresult nsAutoConfig::downloadAutoConfig()
|
||||
There is a possibility of deadlock so we need to make sure
|
||||
that mLoaded will be set to true in any case (success/failure)
|
||||
*/
|
||||
|
||||
while (!mLoaded)
|
||||
NS_ENSURE_STATE(NS_ProcessNextEvent(thread));
|
||||
|
||||
if (!mozilla::SpinEventLoopUntil([&]() { return mLoaded; })) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int32_t minutes;
|
||||
rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval",
|
||||
|
55
gfx/gl/AndroidNativeWindow.h
Normal file
55
gfx/gl/AndroidNativeWindow.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* 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 AndroidNativeWindow_h__
|
||||
#define AndroidNativeWindow_h__
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "SurfaceTexture.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class AndroidNativeWindow {
|
||||
public:
|
||||
AndroidNativeWindow() : mNativeWindow(nullptr) {
|
||||
}
|
||||
|
||||
AndroidNativeWindow(java::sdk::Surface::Param aSurface) {
|
||||
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
|
||||
aSurface.Get());
|
||||
}
|
||||
|
||||
AndroidNativeWindow(java::GeckoSurface::Param aSurface) {
|
||||
auto surf = java::sdk::Surface::LocalRef(java::sdk::Surface::Ref::From(aSurface));
|
||||
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
|
||||
surf.Get());
|
||||
}
|
||||
|
||||
~AndroidNativeWindow() {
|
||||
if (mNativeWindow) {
|
||||
ANativeWindow_release(mNativeWindow);
|
||||
mNativeWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ANativeWindow* NativeWindow() const {
|
||||
return mNativeWindow;
|
||||
}
|
||||
|
||||
private:
|
||||
ANativeWindow* mNativeWindow;
|
||||
};
|
||||
|
||||
} // gl
|
||||
} // mozilla
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
#endif // AndroidNativeWindow_h__
|
@ -1,204 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* 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/. */
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#include <map>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/log.h>
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "GeneratedJNINatives.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class AndroidSurfaceTexture::Listener
|
||||
: public java::SurfaceTextureListener::Natives<Listener>
|
||||
{
|
||||
using Base = java::SurfaceTextureListener::Natives<Listener>;
|
||||
|
||||
const nsCOMPtr<nsIRunnable> mCallback;
|
||||
|
||||
public:
|
||||
using Base::AttachNative;
|
||||
using Base::DisposeNative;
|
||||
|
||||
Listener(nsIRunnable* aCallback) : mCallback(aCallback) {}
|
||||
|
||||
void OnFrameAvailable()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
mCallback->Run();
|
||||
return;
|
||||
}
|
||||
NS_DispatchToMainThread(mCallback);
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<AndroidSurfaceTexture>
|
||||
AndroidSurfaceTexture::Create()
|
||||
{
|
||||
return Create(nullptr, 0);
|
||||
}
|
||||
|
||||
already_AddRefed<AndroidSurfaceTexture>
|
||||
AndroidSurfaceTexture::Create(GLContext* aContext, GLuint aTexture)
|
||||
{
|
||||
RefPtr<AndroidSurfaceTexture> st = new AndroidSurfaceTexture();
|
||||
if (!st->Init(aContext, aTexture)) {
|
||||
printf_stderr("Failed to initialize AndroidSurfaceTexture");
|
||||
st = nullptr;
|
||||
}
|
||||
|
||||
return st.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mAttachedContext == aContext) {
|
||||
NS_WARNING("Tried to attach same GLContext to AndroidSurfaceTexture");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!CanDetach()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
while (mAttachedContext) {
|
||||
// Wait until it's detached (or we time out)
|
||||
if (NS_FAILED(lock.Wait(aTimeout))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aContext->IsOwningThreadCurrent(), "Trying to attach GLContext from different thread");
|
||||
|
||||
aContext->fGenTextures(1, &mTexture);
|
||||
|
||||
if (NS_FAILED(mSurfaceTexture->AttachToGLContext(mTexture))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
mAttachedContext = aContext;
|
||||
mAttachedContext->MakeCurrent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AndroidSurfaceTexture::Detach()
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!CanDetach() ||
|
||||
!mAttachedContext ||
|
||||
!mAttachedContext->IsOwningThreadCurrent())
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mAttachedContext->MakeCurrent();
|
||||
|
||||
mSurfaceTexture->DetachFromGLContext();
|
||||
|
||||
mTexture = 0;
|
||||
mAttachedContext = nullptr;
|
||||
lock.NotifyAll();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidSurfaceTexture::CanDetach() const
|
||||
{
|
||||
// The API for attach/detach only exists on 16+, and PowerVR has some sort of
|
||||
// fencing issue. Additionally, attach/detach seems to be busted on at least
|
||||
// some Mali adapters (400MP2 for sure, bug 1131793)
|
||||
return AndroidBridge::Bridge()->GetAPIVersion() >= 16 &&
|
||||
(!mAttachedContext || mAttachedContext->Vendor() != GLVendor::Imagination) &&
|
||||
(!mAttachedContext || mAttachedContext->Vendor() != GLVendor::ARM /* Mali */) &&
|
||||
gfxPrefs::SurfaceTextureDetachEnabled();
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
{
|
||||
|
||||
if (!aTexture && !CanDetach()) {
|
||||
// We have no texture and cannot initialize detached, bail out
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
java::sdk::SurfaceTexture::New(aTexture, ReturnTo(&mSurfaceTexture))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aTexture) {
|
||||
mSurfaceTexture->DetachFromGLContext();
|
||||
}
|
||||
|
||||
mAttachedContext = aContext;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
java::sdk::Surface::New(mSurfaceTexture, ReturnTo(&mSurface))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
|
||||
mSurface.Get());
|
||||
MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AndroidSurfaceTexture::AndroidSurfaceTexture()
|
||||
: mTexture(0)
|
||||
, mSurfaceTexture()
|
||||
, mSurface()
|
||||
, mAttachedContext(nullptr)
|
||||
, mMonitor("AndroidSurfaceTexture")
|
||||
{
|
||||
}
|
||||
|
||||
AndroidSurfaceTexture::~AndroidSurfaceTexture()
|
||||
{
|
||||
if (mSurfaceTexture) {
|
||||
SetFrameAvailableCallback(nullptr);
|
||||
mSurfaceTexture = nullptr;
|
||||
}
|
||||
|
||||
if (mNativeWindow) {
|
||||
ANativeWindow_release(mNativeWindow);
|
||||
mNativeWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::UpdateTexImage()
|
||||
{
|
||||
mSurfaceTexture->UpdateTexImage();
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
|
||||
AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
|
||||
gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
|
||||
auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
|
||||
mSurfaceTexture->GetTransformMatrix(jarray);
|
||||
aSurfaceTexture->GetTransformMatrix(jarray);
|
||||
|
||||
jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr);
|
||||
|
||||
@ -225,36 +41,6 @@ AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
|
||||
env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
|
||||
{
|
||||
java::SurfaceTextureListener::LocalRef newListener;
|
||||
|
||||
if (aRunnable) {
|
||||
newListener = java::SurfaceTextureListener::New();
|
||||
Listener::AttachNative(newListener, MakeUnique<Listener>(aRunnable));
|
||||
}
|
||||
|
||||
if (aRunnable || mListener) {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
mSurfaceTexture->SetOnFrameAvailableListener(newListener)));
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
Listener::DisposeNative(java::SurfaceTextureListener::LocalRef(
|
||||
newListener.Env(), mListener));
|
||||
}
|
||||
|
||||
mListener = newListener;
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::SetDefaultSize(mozilla::gfx::IntSize size)
|
||||
{
|
||||
mSurfaceTexture->SetDefaultBufferSize(size.width, size.height);
|
||||
}
|
||||
|
||||
} // gl
|
||||
} // mozilla
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
@ -8,100 +8,23 @@
|
||||
#define AndroidSurfaceTexture_h__
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/native_window.h>
|
||||
#include "nsIRunnable.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/MatrixFwd.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "SurfaceTexture.h"
|
||||
|
||||
typedef uint32_t AndroidSurfaceTextureHandle;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
|
||||
/**
|
||||
* This class is a wrapper around Android's SurfaceTexture class.
|
||||
* Usage is pretty much exactly like the Java class, so see
|
||||
* the Android documentation for details.
|
||||
*/
|
||||
class AndroidSurfaceTexture {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidSurfaceTexture)
|
||||
|
||||
public:
|
||||
static void GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
|
||||
mozilla::gfx::Matrix4x4& aMatrix);
|
||||
|
||||
// The SurfaceTexture is created in an attached state. This method requires
|
||||
// Android Ice Cream Sandwich.
|
||||
static already_AddRefed<AndroidSurfaceTexture> Create(GLContext* aGLContext, GLuint aTexture);
|
||||
|
||||
// Here the SurfaceTexture will be created in a detached state. You must call
|
||||
// Attach() with the GLContext you wish to composite with. It must be done
|
||||
// on the thread where that GLContext is current. This method requires
|
||||
// Android Jelly Bean.
|
||||
static already_AddRefed<AndroidSurfaceTexture> Create();
|
||||
|
||||
// If we are on Jelly Bean, the SurfaceTexture can be detached and reattached
|
||||
// to allow consumption from different GLContexts. It is recommended to only
|
||||
// attach while you are consuming in order to allow this.
|
||||
//
|
||||
// Only one GLContext may be attached at any given time. If another is already
|
||||
// attached, we try to wait for it to become detached.
|
||||
nsresult Attach(GLContext* aContext, PRIntervalTime aTiemout = PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
nsresult Detach();
|
||||
|
||||
// Ability to detach is based on API version (16+), and we also block PowerVR
|
||||
// since it has some type of fencing problem. Bug 1100126.
|
||||
bool CanDetach() const;
|
||||
|
||||
GLContext* AttachedContext() const { return mAttachedContext; }
|
||||
|
||||
ANativeWindow* NativeWindow() const {
|
||||
return mNativeWindow;
|
||||
}
|
||||
|
||||
// This attaches the updated data to the TEXTURE_EXTERNAL target
|
||||
void UpdateTexImage();
|
||||
|
||||
void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix) const;
|
||||
|
||||
void SetDefaultSize(mozilla::gfx::IntSize size);
|
||||
|
||||
// The callback is guaranteed to be called on the main thread even
|
||||
// if the upstream callback is received on a different thread
|
||||
void SetFrameAvailableCallback(nsIRunnable* aRunnable);
|
||||
|
||||
GLuint Texture() const { return mTexture; }
|
||||
const java::sdk::Surface::Ref& JavaSurface() const { return mSurface; }
|
||||
|
||||
private:
|
||||
class Listener;
|
||||
|
||||
AndroidSurfaceTexture();
|
||||
~AndroidSurfaceTexture();
|
||||
|
||||
bool Init(GLContext* aContext, GLuint aTexture);
|
||||
|
||||
GLuint mTexture;
|
||||
java::sdk::SurfaceTexture::GlobalRef mSurfaceTexture;
|
||||
java::sdk::Surface::GlobalRef mSurface;
|
||||
java::SurfaceTextureListener::GlobalRef mListener;
|
||||
|
||||
GLContext* mAttachedContext;
|
||||
|
||||
ANativeWindow* mNativeWindow;
|
||||
|
||||
Monitor mMonitor;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // gl
|
||||
} // mozilla
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
#endif // AndroidSurfaceTexture_h__
|
||||
|
@ -684,30 +684,8 @@ GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target)
|
||||
bool
|
||||
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
|
||||
{
|
||||
AndroidSurfaceTexture* surfaceTexture = stImage->GetSurfaceTexture();
|
||||
|
||||
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
|
||||
|
||||
if (NS_FAILED(surfaceTexture->Attach(mGL, PR_MillisecondsToInterval(ATTACH_WAIT_MS))))
|
||||
return false;
|
||||
|
||||
// UpdateTexImage() changes the EXTERNAL binding, so save it here
|
||||
// so we can restore it after.
|
||||
int oldBinding = 0;
|
||||
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &oldBinding);
|
||||
|
||||
surfaceTexture->UpdateTexImage();
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
surfaceTexture->GetTransformMatrix(transform);
|
||||
|
||||
mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &transform._11);
|
||||
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
surfaceTexture->Detach();
|
||||
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
|
||||
return true;
|
||||
// FIXME
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -69,6 +69,9 @@ public:
|
||||
virtual bool ReleaseTexImage() override;
|
||||
|
||||
void SetEGLSurfaceOverride(EGLSurface surf);
|
||||
EGLSurface GetEGLSurfaceOverride() {
|
||||
return mSurfaceOverride;
|
||||
}
|
||||
|
||||
virtual bool MakeCurrentImpl(bool aForce) override;
|
||||
|
||||
|
@ -90,6 +90,12 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
#elif defined(MOZ_WIDGET_UIKIT)
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, mFlags);
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
if (XRE_IsParentProcess()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
} else {
|
||||
factory = SurfaceFactory_SurfaceTexture::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
#else
|
||||
if (gl->GetContextType() == GLContextType::EGL) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
|
@ -96,6 +96,10 @@ public:
|
||||
// Unlocking is harmless if we're already unlocked.
|
||||
void UnlockProd();
|
||||
|
||||
// This surface has been moved to the front buffer and will not be locked again
|
||||
// until it is recycled. Do any finalization steps here.
|
||||
virtual void Commit(){}
|
||||
|
||||
protected:
|
||||
virtual void LockProdImpl() = 0;
|
||||
virtual void UnlockProdImpl() = 0;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
@ -100,12 +101,6 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage()
|
||||
mProdTex = 0;
|
||||
}
|
||||
|
||||
layers::TextureFlags
|
||||
SharedSurface_EGLImage::GetTextureFlags() const
|
||||
{
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_EGLImage::ProducerReleaseImpl()
|
||||
{
|
||||
@ -185,6 +180,136 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
/*static*/ UniquePtr<SharedSurface_SurfaceTexture>
|
||||
SharedSurface_SurfaceTexture::Create(GLContext* prodGL,
|
||||
const GLFormats& formats,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
java::GeckoSurface::Param surface)
|
||||
{
|
||||
MOZ_ASSERT(surface);
|
||||
|
||||
UniquePtr<SharedSurface_SurfaceTexture> ret;
|
||||
|
||||
AndroidNativeWindow window(surface);
|
||||
EGLSurface eglSurface = GLContextProviderEGL::CreateEGLSurface(window.NativeWindow());
|
||||
if (!eglSurface) {
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
ret.reset(new SharedSurface_SurfaceTexture(prodGL, size, hasAlpha,
|
||||
formats, surface, eglSurface));
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
SharedSurface_SurfaceTexture::SharedSurface_SurfaceTexture(GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
const GLFormats& formats,
|
||||
java::GeckoSurface::Param surface,
|
||||
EGLSurface eglSurface)
|
||||
: SharedSurface(SharedSurfaceType::AndroidSurfaceTexture,
|
||||
AttachmentType::Screen,
|
||||
gl,
|
||||
size,
|
||||
hasAlpha,
|
||||
true)
|
||||
, mSurface(surface)
|
||||
, mEglSurface(eglSurface)
|
||||
{
|
||||
}
|
||||
|
||||
SharedSurface_SurfaceTexture::~SharedSurface_SurfaceTexture()
|
||||
{
|
||||
GLContextProviderEGL::DestroyEGLSurface(mEglSurface);
|
||||
java::SurfaceAllocator::DisposeSurface(mSurface);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::LockProdImpl()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
GLContextEGL *gl = GLContextEGL::Cast(mGL);
|
||||
mOrigEglSurface = gl->GetEGLSurfaceOverride();
|
||||
gl->SetEGLSurfaceOverride(mEglSurface);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::UnlockProdImpl()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
GLContextEGL *gl = GLContextEGL::Cast(mGL);
|
||||
MOZ_ASSERT(gl->GetEGLSurfaceOverride() == mEglSurface);
|
||||
|
||||
gl->SetEGLSurfaceOverride(mOrigEglSurface);
|
||||
mOrigEglSurface = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::Commit()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
LockProdImpl();
|
||||
mGL->SwapBuffers();
|
||||
UnlockProdImpl();
|
||||
mSurface->SetAvailable(false);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::WaitForBufferOwnership()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mSurface->GetAvailable());
|
||||
mSurface->SetAvailable(true);
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_SurfaceTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
*out_descriptor = layers::SurfaceTextureDescriptor(mSurface->GetHandle(), mSize, false /* NOT continuous */);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_SurfaceTexture>
|
||||
SurfaceFactory_SurfaceTexture::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::LayersIPCChannel>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
UniquePtr<SurfaceFactory_SurfaceTexture> ret(
|
||||
new SurfaceFactory_SurfaceTexture(prodGL, caps, allocator, flags));
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
UniquePtr<SharedSurface>
|
||||
SurfaceFactory_SurfaceTexture::CreateShared(const gfx::IntSize& size)
|
||||
{
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
|
||||
jni::Object::LocalRef surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, true);
|
||||
if (!surface) {
|
||||
// Try multi-buffer mode
|
||||
surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, false);
|
||||
if (!surface) {
|
||||
// Give up
|
||||
NS_WARNING("Failed to allocate SurfaceTexture!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return SharedSurface_SurfaceTexture::Create(mGL, mFormats, size, hasAlpha,
|
||||
java::GeckoSurface::Ref::From(surface));
|
||||
}
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "SharedSurface.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "AndroidNativeWindow.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
@ -58,7 +63,9 @@ protected:
|
||||
public:
|
||||
virtual ~SharedSurface_EGLImage();
|
||||
|
||||
virtual layers::TextureFlags GetTextureFlags() const override;
|
||||
virtual layers::TextureFlags GetTextureFlags() const override {
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
virtual void LockProdImpl() override {}
|
||||
virtual void UnlockProdImpl() override {}
|
||||
@ -110,6 +117,90 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class SharedSurface_SurfaceTexture
|
||||
: public SharedSurface
|
||||
{
|
||||
public:
|
||||
static UniquePtr<SharedSurface_SurfaceTexture> Create(GLContext* prodGL,
|
||||
const GLFormats& formats,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
java::GeckoSurface::Param surface);
|
||||
|
||||
static SharedSurface_SurfaceTexture* Cast(SharedSurface* surf) {
|
||||
MOZ_ASSERT(surf->mType == SharedSurfaceType::AndroidSurfaceTexture);
|
||||
|
||||
return (SharedSurface_SurfaceTexture*)surf;
|
||||
}
|
||||
|
||||
java::GeckoSurface::Param JavaSurface() { return mSurface; }
|
||||
|
||||
protected:
|
||||
java::GeckoSurface::GlobalRef mSurface;
|
||||
EGLSurface mEglSurface;
|
||||
EGLSurface mOrigEglSurface;
|
||||
|
||||
SharedSurface_SurfaceTexture(GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
const GLFormats& formats,
|
||||
java::GeckoSurface::Param surface,
|
||||
EGLSurface eglSurface);
|
||||
|
||||
public:
|
||||
virtual ~SharedSurface_SurfaceTexture();
|
||||
|
||||
virtual layers::TextureFlags GetTextureFlags() const override {
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
virtual void LockProdImpl() override;
|
||||
virtual void UnlockProdImpl() override;
|
||||
|
||||
virtual void ProducerAcquireImpl() override {}
|
||||
virtual void ProducerReleaseImpl() override {}
|
||||
|
||||
virtual void ProducerReadAcquireImpl() override {}
|
||||
virtual void ProducerReadReleaseImpl() override {}
|
||||
|
||||
// Implementation-specific functions below:
|
||||
// Returns texture and target
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
|
||||
|
||||
virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override { return false; }
|
||||
|
||||
virtual void Commit() override;
|
||||
|
||||
virtual void WaitForBufferOwnership() override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SurfaceFactory_SurfaceTexture
|
||||
: public SurfaceFactory
|
||||
{
|
||||
public:
|
||||
// Fallible:
|
||||
static UniquePtr<SurfaceFactory_SurfaceTexture> Create(GLContext* prodGL,
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::LayersIPCChannel>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
protected:
|
||||
SurfaceFactory_SurfaceTexture(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::LayersIPCChannel>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
: SurfaceFactory(SharedSurfaceType::AndroidSurfaceTexture, prodGL, caps, allocator, flags)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
@ -77,6 +77,7 @@ enum class SharedSurfaceType : uint8_t {
|
||||
IOSurface,
|
||||
GLXDrawable,
|
||||
SharedGLTexture,
|
||||
AndroidSurfaceTexture,
|
||||
|
||||
Max
|
||||
};
|
||||
|
@ -24,6 +24,7 @@ if CONFIG['MOZ_GL_PROVIDER']:
|
||||
gl_provider = CONFIG['MOZ_GL_PROVIDER']
|
||||
|
||||
EXPORTS += [
|
||||
'AndroidNativeWindow.h',
|
||||
'AndroidSurfaceTexture.h',
|
||||
'DecomposeIntoNoRepeatTriangles.h',
|
||||
'EGLUtils.h',
|
||||
|
@ -98,14 +98,17 @@ GLImage::GetAsSourceSurface()
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
SurfaceTextureImage::SurfaceTextureImage(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
SurfaceTextureImage::SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
|
||||
const gfx::IntSize& aSize,
|
||||
bool aContinuous,
|
||||
gl::OriginPos aOriginPos)
|
||||
: GLImage(ImageFormat::SURFACE_TEXTURE),
|
||||
mSurfaceTexture(aSurfTex),
|
||||
mHandle(aHandle),
|
||||
mSize(aSize),
|
||||
mContinuous(aContinuous),
|
||||
mOriginPos(aOriginPos)
|
||||
{
|
||||
MOZ_ASSERT(mHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -64,13 +64,17 @@ private:
|
||||
|
||||
class SurfaceTextureImage : public GLImage {
|
||||
public:
|
||||
SurfaceTextureImage(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
|
||||
const gfx::IntSize& aSize,
|
||||
bool aContinuous,
|
||||
gl::OriginPos aOriginPos);
|
||||
|
||||
gfx::IntSize GetSize() override { return mSize; }
|
||||
gl::AndroidSurfaceTexture* GetSurfaceTexture() const {
|
||||
return mSurfaceTexture;
|
||||
AndroidSurfaceTextureHandle GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
bool GetContinuous() const {
|
||||
return mContinuous;
|
||||
}
|
||||
gl::OriginPos GetOriginPos() const {
|
||||
return mOriginPos;
|
||||
@ -81,8 +85,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<gl::AndroidSurfaceTexture> mSurfaceTexture;
|
||||
AndroidSurfaceTextureHandle mHandle;
|
||||
gfx::IntSize mSize;
|
||||
bool mContinuous;
|
||||
gl::OriginPos mOriginPos;
|
||||
};
|
||||
|
||||
|
@ -278,10 +278,15 @@ AndroidDynamicToolbarAnimator::SetCompositionSize(ScreenIntSize aSize)
|
||||
return false;
|
||||
}
|
||||
|
||||
ScreenIntCoord prevHeight = mCompositorCompositionSize.height;
|
||||
ScreenIntSize prevSize = mCompositorCompositionSize;
|
||||
mCompositorCompositionSize = aSize;
|
||||
|
||||
if (prevHeight != aSize.height) {
|
||||
// The width has changed so the static snapshot needs to be updated
|
||||
if ((prevSize.width != aSize.width) && (mToolbarState != eToolbarVisible)) {
|
||||
PostMessage(STATIC_TOOLBAR_NEEDS_UPDATE);
|
||||
}
|
||||
|
||||
if (prevSize.height != aSize.height) {
|
||||
UpdateControllerCompositionHeight(aSize.height);
|
||||
UpdateFixedLayerMargins();
|
||||
}
|
||||
|
@ -461,6 +461,8 @@ CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRendere
|
||||
mReadbackClient = nullptr;
|
||||
}
|
||||
|
||||
surf->Commit();
|
||||
|
||||
if (asyncRenderer) {
|
||||
// If surface type is Basic, above codes will readback
|
||||
// the GLContext to mReadbackClient in order to send frame to
|
||||
|
@ -132,7 +132,7 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
|
||||
} else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
|
||||
SurfaceTextureImage* typedImage = aImage->AsSurfaceTextureImage();
|
||||
texture = AndroidSurfaceTextureData::CreateTextureClient(
|
||||
typedImage->GetSurfaceTexture(), size, typedImage->GetOriginPos(),
|
||||
typedImage->GetHandle(), size, typedImage->GetContinuous(), typedImage->GetOriginPos(),
|
||||
aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
|
||||
#endif
|
||||
} else {
|
||||
|
@ -601,7 +601,7 @@ protected:
|
||||
/**
|
||||
* Called when mCompositableCount becomes 0.
|
||||
*/
|
||||
void NotifyNotUsed();
|
||||
virtual void NotifyNotUsed();
|
||||
|
||||
// for Compositor.
|
||||
void CallNotifyNotUsed();
|
||||
|
@ -192,9 +192,7 @@ CompositorBridgeChild::ShutDown()
|
||||
{
|
||||
if (sCompositorBridge) {
|
||||
sCompositorBridge->Destroy();
|
||||
do {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
} while (sCompositorBridge);
|
||||
SpinEventLoopUntil([&]() { return !sCompositorBridge; });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,9 +132,7 @@ CompositorThreadHolder::Shutdown()
|
||||
|
||||
// No locking is needed around sFinishedCompositorShutDown because it is only
|
||||
// ever accessed on the main thread.
|
||||
while (!sFinishedCompositorShutDown) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
SpinEventLoopUntil([&]() { return sFinishedCompositorShutDown; });
|
||||
|
||||
CompositorBridgeParent::FinishShutdown();
|
||||
}
|
||||
|
@ -60,8 +60,9 @@ struct SurfaceDescriptorMacIOSurface {
|
||||
};
|
||||
|
||||
struct SurfaceTextureDescriptor {
|
||||
uintptr_t surfTex;
|
||||
uint64_t handle;
|
||||
IntSize size;
|
||||
bool continuous;
|
||||
};
|
||||
|
||||
struct EGLImageDescriptor {
|
||||
|
@ -79,34 +79,31 @@ EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
|
||||
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
|
||||
gfx::IntSize aSize,
|
||||
bool aContinuous,
|
||||
gl::OriginPos aOriginPos,
|
||||
LayersIPCChannel* aAllocator,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Can't pass an android surfaces between processes.");
|
||||
|
||||
if (!aSurfTex || !XRE_IsParentProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOriginPos == gl::OriginPos::BottomLeft) {
|
||||
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
}
|
||||
|
||||
return TextureClient::CreateWithData(
|
||||
new AndroidSurfaceTextureData(aSurfTex, aSize),
|
||||
new AndroidSurfaceTextureData(aHandle, aSize, aContinuous),
|
||||
aFlags, aAllocator
|
||||
);
|
||||
}
|
||||
|
||||
AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize)
|
||||
: mSurfTex(aSurfTex)
|
||||
AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
|
||||
gfx::IntSize aSize, bool aContinuous)
|
||||
: mHandle(aHandle)
|
||||
, mSize(aSize)
|
||||
{}
|
||||
, mContinuous(aContinuous)
|
||||
{
|
||||
MOZ_ASSERT(mHandle);
|
||||
}
|
||||
|
||||
AndroidSurfaceTextureData::~AndroidSurfaceTextureData()
|
||||
{}
|
||||
@ -125,8 +122,7 @@ AndroidSurfaceTextureData::FillInfo(TextureData::Info& aInfo) const
|
||||
bool
|
||||
AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(),
|
||||
mSize);
|
||||
aOutDescriptor = SurfaceTextureDescriptor(mHandle, mSize, mContinuous);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,9 @@ class AndroidSurfaceTextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
|
||||
gfx::IntSize aSize,
|
||||
bool aContinuous,
|
||||
gl::OriginPos aOriginPos,
|
||||
LayersIPCChannel* aAllocator,
|
||||
TextureFlags aFlags);
|
||||
@ -75,10 +76,11 @@ public:
|
||||
virtual void Deallocate(LayersIPCChannel*) override {}
|
||||
|
||||
protected:
|
||||
AndroidSurfaceTextureData(gl::AndroidSurfaceTexture* aSurfTex, gfx::IntSize aSize);
|
||||
AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous);
|
||||
|
||||
const RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
|
||||
const AndroidSurfaceTextureHandle mHandle;
|
||||
const gfx::IntSize mSize;
|
||||
const bool mContinuous;
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
@ -56,9 +56,14 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
|
||||
const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
|
||||
java::GeckoSurfaceTexture::LocalRef surfaceTexture = java::GeckoSurfaceTexture::Lookup(desc.handle());
|
||||
|
||||
MOZ_RELEASE_ASSERT(surfaceTexture);
|
||||
|
||||
result = new SurfaceTextureHost(aFlags,
|
||||
(AndroidSurfaceTexture*)desc.surfTex(),
|
||||
desc.size());
|
||||
surfaceTexture,
|
||||
desc.size(),
|
||||
desc.continuous());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -335,7 +340,7 @@ GLTextureSource::IsValid() const
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
SurfaceTextureSource::SurfaceTextureSource(TextureSourceProvider* aProvider,
|
||||
AndroidSurfaceTexture* aSurfTex,
|
||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget,
|
||||
GLenum aWrapMode,
|
||||
@ -361,12 +366,7 @@ SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
|
||||
}
|
||||
|
||||
gl->fActiveTexture(aTextureUnit);
|
||||
|
||||
// SurfaceTexture spams us if there are any existing GL errors, so
|
||||
// we'll clear them here in order to avoid that.
|
||||
gl->FlushErrors();
|
||||
|
||||
mSurfTex->UpdateTexImage();
|
||||
gl->fBindTexture(mTextureTarget, mSurfTex->GetTexName());
|
||||
|
||||
ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
|
||||
}
|
||||
@ -395,7 +395,9 @@ SurfaceTextureSource::GetTextureTransform()
|
||||
MOZ_ASSERT(mSurfTex);
|
||||
|
||||
gfx::Matrix4x4 ret;
|
||||
mSurfTex->GetTransformMatrix(ret);
|
||||
|
||||
const auto& surf = java::sdk::SurfaceTexture::LocalRef(java::sdk::SurfaceTexture::Ref::From(mSurfTex));
|
||||
AndroidSurfaceTexture::GetTransformMatrix(surf, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -409,18 +411,39 @@ SurfaceTextureSource::DeallocateDeviceData()
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags,
|
||||
AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize)
|
||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
bool aContinuousUpdate)
|
||||
: TextureHost(aFlags)
|
||||
, mSurfTex(aSurfTex)
|
||||
, mSize(aSize)
|
||||
, mContinuousUpdate(aContinuousUpdate)
|
||||
{
|
||||
// Continuous update makes no sense with single buffer mode
|
||||
MOZ_ASSERT(!mSurfTex->IsSingleBuffer() || !mContinuousUpdate);
|
||||
}
|
||||
|
||||
SurfaceTextureHost::~SurfaceTextureHost()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
|
||||
{
|
||||
GLContext* gl = this->gl();
|
||||
if (!gl || !gl->MakeCurrent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContinuousUpdate) {
|
||||
// UpdateTexImage() advances the internal buffer queue, so we only want to call this
|
||||
// once per transactionwhen we are not in continuous mode (as we are here). Otherwise,
|
||||
// the SurfaceTexture content will be de-synced from the rest of the page in subsequent
|
||||
// compositor passes.
|
||||
mSurfTex->UpdateTexImage();
|
||||
}
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
SurfaceTextureHost::gl() const
|
||||
{
|
||||
@ -436,9 +459,13 @@ SurfaceTextureHost::Lock()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mContinuousUpdate) {
|
||||
mSurfTex->UpdateTexImage();
|
||||
}
|
||||
|
||||
if (!mTextureSource) {
|
||||
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
|
||||
GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
GLenum target = LOCAL_GL_TEXTURE_EXTERNAL; // This is required by SurfaceTexture
|
||||
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
|
||||
mTextureSource = new SurfaceTextureSource(mProvider,
|
||||
mSurfTex,
|
||||
@ -448,14 +475,7 @@ SurfaceTextureHost::Lock()
|
||||
mSize);
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(mSurfTex->Attach(gl));
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureHost::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mSurfTex);
|
||||
mSurfTex->Detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -474,6 +494,16 @@ SurfaceTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureHost::NotifyNotUsed()
|
||||
{
|
||||
if (mSurfTex->IsSingleBuffer()) {
|
||||
mSurfTex->ReleaseTexImage();
|
||||
}
|
||||
|
||||
TextureHost::NotifyNotUsed();
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
SurfaceTextureHost::GetFormat() const
|
||||
{
|
||||
|
@ -31,15 +31,16 @@
|
||||
#include "nsRegionFwd.h" // for nsIntRegion
|
||||
#include "OGLShaderProgram.h" // for ShaderProgramType, etc
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class DataSourceSurface;
|
||||
} // namespace gfx
|
||||
|
||||
namespace gl {
|
||||
class AndroidSurfaceTexture;
|
||||
} // namespace gl
|
||||
|
||||
namespace layers {
|
||||
|
||||
class Compositor;
|
||||
@ -341,7 +342,7 @@ class SurfaceTextureSource : public TextureSource
|
||||
{
|
||||
public:
|
||||
SurfaceTextureSource(TextureSourceProvider* aProvider,
|
||||
mozilla::gl::AndroidSurfaceTexture* aSurfTex,
|
||||
java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget,
|
||||
GLenum aWrapMode,
|
||||
@ -376,7 +377,7 @@ public:
|
||||
|
||||
protected:
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
|
||||
mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
|
||||
const gfx::SurfaceFormat mFormat;
|
||||
const GLenum mTextureTarget;
|
||||
const GLenum mWrapMode;
|
||||
@ -387,21 +388,24 @@ class SurfaceTextureHost : public TextureHost
|
||||
{
|
||||
public:
|
||||
SurfaceTextureHost(TextureFlags aFlags,
|
||||
mozilla::gl::AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize);
|
||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
bool aContinuousUpdate);
|
||||
|
||||
virtual ~SurfaceTextureHost();
|
||||
|
||||
virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
|
||||
|
||||
virtual void DeallocateDeviceData() override;
|
||||
|
||||
virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
virtual void NotifyNotUsed() override;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
|
||||
{
|
||||
aTexture = mTextureSource;
|
||||
@ -420,8 +424,9 @@ public:
|
||||
virtual const char* Name() override { return "SurfaceTextureHost"; }
|
||||
|
||||
protected:
|
||||
RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
|
||||
mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
|
||||
const gfx::IntSize mSize;
|
||||
bool mContinuousUpdate;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
RefPtr<SurfaceTextureSource> mTextureSource;
|
||||
};
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include "nsDebug.h" // for NS_ASSERTION, NS_ERROR, etc
|
||||
#include "nsDeque.h" // for nsDeque
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "GeneratedJNINatives.h"
|
||||
#endif
|
||||
|
||||
#define TEXTURE_POOL_SIZE 10
|
||||
|
||||
namespace mozilla {
|
||||
@ -20,6 +24,19 @@ static GLContext* sActiveContext = nullptr;
|
||||
static Monitor* sMonitor = nullptr;
|
||||
static nsDeque* sTextures = nullptr;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class GeckoSurfaceTextureSupport final
|
||||
: public java::GeckoSurfaceTexture::Natives<GeckoSurfaceTextureSupport>
|
||||
{
|
||||
public:
|
||||
static int32_t NativeAcquireTexture() {
|
||||
return TexturePoolOGL::AcquireTexture();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
GLuint TexturePoolOGL::AcquireTexture()
|
||||
{
|
||||
NS_ASSERTION(sMonitor, "not initialized");
|
||||
@ -111,6 +128,12 @@ void TexturePoolOGL::Init()
|
||||
{
|
||||
sMonitor = new Monitor("TexturePoolOGL.sMonitor");
|
||||
sTextures = new nsDeque();
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (jni::IsAvailable()) {
|
||||
GeckoSurfaceTextureSupport::Init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TexturePoolOGL::Shutdown()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user