merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: 47jGmg0qsJV
This commit is contained in:
Sebastian Hengst 2017-09-03 10:54:14 +02:00
Родитель d7992cb0de 8ad8b56fea
Коммит 7afb65280a
59 изменённых файлов: 11384 добавлений и 3112 удалений

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

@ -12,7 +12,7 @@
/* Customs properties */
--title-font-size: 24px;
--ui-element-font-size: 16px;
--primary-line-height: 30px;
--primary-line-height: 22px;
--secondary-line-height: 25px;
--base-spacing: 20px;
--base-transition: all 0.25s ease;
@ -55,7 +55,7 @@
justify-content: center;
}
.landing-page .panel input[type=button] {
.landing-page button {
background-color: var(--theme-tab-toolbar-background);
color: var(--theme-comment);
font-size: var(--ui-element-font-size);
@ -63,6 +63,7 @@
padding: calc(var(--base-spacing) / 2);
margin: 0 var(--base-spacing);
transition: var(--base-transition);
cursor: pointer;
}
.landing-page .panel header h1 {
@ -103,6 +104,27 @@
font-size: 14px;
color: var(--theme-comment);
}
.landing-page .panel .launch-action-container {
text-align: center;
}
.landing-page .panel .under-construction {
display: flex;
width: 417px;
color: var(--theme-comment);
font-size: calc(var(--ui-element-font-size) / 1);
margin: var(--base-spacing) auto;
line-height: 1.4em;
}
.landing-page .panel .under-construction .under-construction-message {
max-width: 350px;
}
.landing-page .panel .under-construction .github-link {
display: block;
}
/* 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/. */
@ -170,9 +192,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.landing-page .sidebar {
--sidebar-width: 200px;
display: flex;
background-color: var(--theme-tab-toolbar-background);
width: 200px;
width: var(--sidebar-width);
flex-direction: column;
border-right: 1px solid var(--theme-splitter-color);
}
@ -182,8 +205,8 @@
font-size: var(--title-font-size);
margin: 0;
line-height: var(--primary-line-height);
font-weight: normal;
padding: calc(2 * var(--base-spacing)) var(--base-spacing);
font-weight: bold;
padding: var(--base-spacing) var(--base-spacing);
}
.landing-page .sidebar ul {
@ -222,6 +245,35 @@
.landing-page .sidebar li:focus a {
color: inherit;
}
.landing-page .sidebar li:last-child {
border-top: 2px solid var(--theme-splitter-color);
margin: 2px;
}
.landing-page .sidebar .title-wrapper .launchpad-container {
padding-left: var(--base-spacing);
}
.landing-page .sidebar .title-wrapper .launchpad-container .launchpad-container-icon {
display: inline-block;
}
.landing-page .sidebar .title-wrapper .launchpad-container svg {
width: 24px;
height: 24px;
}
.landing-page .sidebar .title-wrapper .launchpad-container svg path {
width: 24px;
height: 24px;
fill: var(--theme-body-color);
}
.landing-page .sidebar .title-wrapper .launchpad-container .launchpad-container-title {
display: inline;
padding-left: 3px;
}
/* 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/. */
@ -439,11 +491,11 @@ menuitem:hover {
color: white;
}
menuitem[disabled=true] {
menuitem[disabled="true"] {
color: #cccccc;
}
menuitem[disabled=true]:hover {
menuitem[disabled="true"]:hover {
background-color: transparent;
cursor: default;
}
@ -1006,13 +1058,14 @@ html[dir="rtl"] .managed-tree .tree .node > div {
display: flex;
flex-direction: column;
overflow-y: hidden;
height: 100%;
}
.project-text-search .result {
display: flex;
cursor: default;
margin-bottom: 1px;
padding: 4px 0 4px 30px;
line-height: 16px;
font-size: 10px;
}
@ -1049,8 +1102,7 @@ html[dir="rtl"] .managed-tree .tree .node > div {
font-weight: bold;
line-height: 20px;
cursor: default;
margin: 2px 0;
padding: 3px 0 3px 5px;
padding: 2px 0 2px 5px;
font-size: 12px;
}
@ -1075,6 +1127,11 @@ html[dir="rtl"] .managed-tree .tree .node > div {
.project-text-search .managed-tree {
overflow-y: auto;
height: calc(100% - 81px);
}
.project-text-search .managed-tree .tree {
height: 100%;
}
.autocomplete {
position: relative;
@ -1132,7 +1189,7 @@ html[dir="rtl"] .managed-tree .tree .node > div {
color: white;
}
.theme-dark .result-list.small li.selected {
.theme-dark .result-list.small li.selected {
background-color: var(--theme-body-background);
}
@ -1324,7 +1381,7 @@ html[dir="rtl"] .managed-tree .tree .node > div {
transition: all 0.25s ease;
overflow: hidden;
padding: 5px;
margin-bottom: 4px;
margin-bottom: 0px;
margin-top: -1px;
}
@ -1925,7 +1982,7 @@ html[dir="rtl"] .arrow svg,
.bracket-arrow::before,
.bracket-arrow::after {
content: '';
content: "";
height: 0;
width: 0;
position: absolute;
@ -1970,7 +2027,7 @@ html[dir="rtl"] .arrow svg,
height: 5px;
padding-top: 5px;
}
.popover .preview {
.popover .preview-popup {
background: var(--theme-body-background);
width: 350px;
min-height: 80px;
@ -1983,11 +2040,11 @@ html[dir="rtl"] .arrow svg,
box-shadow: 1px 2px 3px var(--popup-shadow-color);
}
.theme-dark .popover .preview {
.theme-dark .popover .preview-popup {
box-shadow: 1px 2px 3px var(--popup-shadow-color);
}
.popover .preview .header {
.popover .preview-popup .header {
width: 100%;
line-height: 20px;
border-bottom: 1px solid #cccccc;
@ -1995,36 +2052,40 @@ html[dir="rtl"] .arrow svg,
flex-direction: column;
}
.popover .preview .header .link {
.popover .preview-popup .header .link {
align-self: flex-end;
color: var(--theme-highlight-blue);
text-decoration: underline;
}
.selection,
.debug-expression.selection {
.preview-selection:hover {
cursor: default;
}
.preview-selection,
.debug-expression.preview-selection {
background-color: var(--theme-highlight-yellow);
}
.theme-dark .selection,
.theme-dark .debug-expression.selection {
.theme-dark .preview-selection,
.theme-dark .debug-expression.preview-selection {
background-color: #743884;
}
.theme-dark .cm-s-mozilla .selection,
.theme-dark .cm-s-mozilla .debug-expression.selection {
.theme-dark .cm-s-mozilla .preview-selection,
.theme-dark .cm-s-mozilla .debug-expression.preview-selection {
color: #e7ebee;
}
.popover .preview .function-signature {
.popover .preview-popup .function-signature {
padding-top: 10px;
}
.theme-dark .popover .preview {
.theme-dark .popover .preview-popup {
border-color: var(--theme-body-color);
}
.theme-dark .popover .preview .arrow svg {
.theme-dark .popover .preview-popup .arrow svg {
fill: var(--theme-content-color3);
}
@ -2033,7 +2094,7 @@ html[dir="rtl"] .arrow svg,
z-index: 100;
}
.tooltip .preview {
.tooltip .preview-popup {
background: var(--theme-toolbar-background);
max-width: inherit;
min-height: 80px;
@ -2046,7 +2107,7 @@ html[dir="rtl"] .arrow svg,
overflow: auto;
}
.theme-dark .tooltip .preview {
.theme-dark .tooltip .preview-popup {
border-color: var(--theme-body-color);
}
@ -2128,6 +2189,9 @@ html[dir="rtl"] .arrow svg,
.theme-dark .call-site-bp::before {
border-bottom-color: #dd4d4d;
}
.empty-line .CodeMirror-linenumber {
opacity: 0.5;
}
.editor-wrapper {
--debug-line-border: rgb(145, 188, 219);
--debug-expression-background: rgba(202, 227, 255, 0.5);
@ -2827,6 +2891,10 @@ html .breakpoints-list .breakpoint.paused {
font-size: 12px;
}
.accordion div:last-child ._content {
border-bottom: none;
}
.accordion ._header .header-buttons {
display: flex;
margin-left: auto;
@ -2864,6 +2932,10 @@ html .breakpoints-list .breakpoint.paused {
background-color: var(--theme-body-background);
}
.command-bar.vertical {
width: 100vw;
}
html[dir="rtl"] .command-bar {
border-right: 1px solid var(--theme-splitter-color);
}
@ -3016,6 +3088,11 @@ html .command-bar > button:disabled {
z-index: 100;
}
.alignlabel {
display: inline-block;
text-align: left;
}
.welcomebox .toggle-button-end {
position: absolute;
top: auto;
@ -3041,15 +3118,21 @@ html .welcomebox .toggle-button-end.collapsed {
}
.source-header .new-tab-btn {
padding: 0px 4px;
padding: 4px;
margin-top: 4px;
margin-left: 2px;
fill: var(--theme-content-color3);
transition: 0.1s ease;
align-self: center;
}
.source-header .new-tab-btn:hover {
background-color: var(--theme-toolbar-background-hover);
}
.source-header .new-tab-btn svg {
width: 12px;
display: block;
}
.source-tabs {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -3779,6 +3779,14 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-
&& token.type.label != ".")) {
return true;
}
if (lastToken.value == "let") {
return true;
}
if (lastToken.value == "const") {
return true;
}
}
if (token.type.isAssign) {
@ -4582,6 +4590,18 @@ SourceMapGenerator.prototype.applySourceMap =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
// When aOriginal is truthy but has empty values for .line and .column,
// it is most likely a programmer error. In this case we throw a very
// specific error message to try to guide them the right way.
// For example: https://github.com/Polymer/polymer-bundler/pull/519
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
throw new Error(
'original.line and original.column are not numbers -- you probably meant to omit ' +
'the original mapping entirely and only map the generated position. If so, pass ' +
'null for the original mapping instead of an object with empty or null values.'
);
}
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@ -5386,6 +5406,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate
var util = __webpack_require__(819);
var has = Object.prototype.hasOwnProperty;
var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@ -5395,7 +5416,7 @@ var has = Object.prototype.hasOwnProperty;
*/
function ArraySet() {
this._array = [];
this._set = Object.create(null);
this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@ -5416,7 +5437,7 @@ ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
return Object.getOwnPropertyNames(this._set).length;
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@ -5425,14 +5446,18 @@ ArraySet.prototype.size = function ArraySet_size() {
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var sStr = util.toSetString(aStr);
var isDuplicate = has.call(this._set, sStr);
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
this._set[sStr] = idx;
if (hasNativeMap) {
this._set.set(aStr, idx);
} else {
this._set[sStr] = idx;
}
}
};
@ -5442,8 +5467,12 @@ ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
var sStr = util.toSetString(aStr);
return has.call(this._set, sStr);
if (hasNativeMap) {
return this._set.has(aStr);
} else {
var sStr = util.toSetString(aStr);
return has.call(this._set, sStr);
}
};
/**
@ -5452,10 +5481,18 @@ ArraySet.prototype.has = function ArraySet_has(aStr) {
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
var sStr = util.toSetString(aStr);
if (has.call(this._set, sStr)) {
return this._set[sStr];
if (hasNativeMap) {
var idx = this._set.get(aStr);
if (idx >= 0) {
return idx;
}
} else {
var sStr = util.toSetString(aStr);
if (has.call(this._set, sStr)) {
return this._set[sStr];
}
}
throw new Error('"' + aStr + '" is not in the set.');
};
@ -6964,13 +7001,19 @@ SourceNode.fromStringWithSourceMap =
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
// Processed fragments are removed from this array, by calling `shiftNextLine`.
// Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
var remainingLinesIndex = 0;
var shiftNextLine = function() {
var lineContents = remainingLines.shift();
var lineContents = getNextLine();
// The last line of a file might not have a newline.
var newLine = remainingLines.shift() || "";
var newLine = getNextLine() || "";
return lineContents + newLine;
function getNextLine() {
return remainingLinesIndex < remainingLines.length ?
remainingLines[remainingLinesIndex++] : undefined;
}
};
// We need to remember the position of "remainingLines"
@ -6995,10 +7038,10 @@ SourceNode.fromStringWithSourceMap =
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
var nextLine = remainingLines[0];
var nextLine = remainingLines[remainingLinesIndex];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[0] = nextLine.substr(mapping.generatedColumn -
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@ -7015,21 +7058,21 @@ SourceNode.fromStringWithSourceMap =
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[0];
var nextLine = remainingLines[remainingLinesIndex];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
if (remainingLines.length > 0) {
if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
node.add(remainingLines.join(""));
node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@ -7412,12 +7455,17 @@ function workerHandler(publicInterface) {
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }), err => self.postMessage({ id, error: err }));
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
self.postMessage({ id, error });
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -11,6 +11,7 @@ support-files =
examples/sourcemaps2/main.min.js
examples/sourcemaps2/main.js
examples/sourcemaps2/main.js.map
examples/doc-async.html
examples/doc-asm.html
examples/doc-scripts.html
examples/doc-script-mutate.html
@ -26,6 +27,7 @@ support-files =
examples/doc-sources.html
examples/doc-return-values.html
examples/asm.js
examples/async.js
examples/bogus-map.js
examples/entry.js
examples/exceptions.js
@ -42,6 +44,7 @@ support-files =
examples/script-switching-01.js
examples/times2.js
[browser_dbg-async-stepping.js]
[browser_dbg-breaking.js]
[browser_dbg-breaking-from-console.js]
[browser_dbg-breakpoints.js]

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

@ -0,0 +1,30 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests async stepping will:
// 1. step over await statements
// 2. step into async functions
// 3. step out of async functions
add_task(async function test() {
Services.prefs.setBoolPref("devtools.debugger.features.async-stepping", true);
const dbg = await initDebugger("doc-async.html", "async");
await selectSource(dbg, "async");
await addBreakpoint(dbg, "async", 8);
invokeInTab("main");
await waitForPaused(dbg);
assertPausedLocation(dbg);
assertDebugLine(dbg, 8);
await stepOver(dbg);
assertPausedLocation(dbg);
assertDebugLine(dbg, 9);
});
registerCleanupFunction(() => {
Services.prefs.clearUserPref(
"devtools.debugger.features.async-stepping",
false
);
});

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

@ -32,7 +32,7 @@ add_task(function*() {
yield selectSource(dbg, source.url);
yield addBreakpoint(dbg, 5);
yield addBreakpoint(dbg, 2);
yield addBreakpoint(dbg, 4);
const syncedBps = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
yield reload(dbg, "simple1");

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

@ -16,12 +16,16 @@ function getLineEl(dbg, line) {
function assertEditorBreakpoint(dbg, line, shouldExist) {
const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
ok(exists === shouldExist,
"Breakpoint " + (shouldExist ? "exists" : "does not exist") +
" on line " + line);
ok(
exists === shouldExist,
"Breakpoint " +
(shouldExist ? "exists" : "does not exist") +
" on line " +
line
);
}
add_task(function* () {
add_task(function*() {
const dbg = yield initDebugger("doc-scripts.html");
const { selectors: { getBreakpoints, getBreakpoint }, getState } = dbg;
const source = findSource(dbg, "simple1.js");
@ -39,26 +43,4 @@ add_task(function* () {
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
is(getBreakpoints(getState()).size, 0, "No breakpoints exist");
assertEditorBreakpoint(dbg, 4, false);
// Test that a breakpoint icon slides down to the correct line.
clickGutter(dbg, 2);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
ok(getBreakpoint(getState(), { sourceId: source.id, line: 4 }),
"Breakpoint has correct line");
assertEditorBreakpoint(dbg, 2, false);
assertEditorBreakpoint(dbg, 4, true);
// Do the same sliding and make sure it works if there's already a
// breakpoint.
clickGutter(dbg, 2);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
assertEditorBreakpoint(dbg, 2, false);
assertEditorBreakpoint(dbg, 4, true);
clickGutter(dbg, 4);
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
is(getBreakpoints(getState()).size, 0, "No breakpoints exist");
assertEditorBreakpoint(dbg, 4, false);
});

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

@ -44,7 +44,7 @@ add_task(function*() {
// Make sure the source is in the loading state, wait for it to be
// fully loaded, and check the highlighted line.
const simple1 = findSource(dbg, "simple1.js");
ok(getSource(getState(), simple1.id).get("loading"));
ok(getSource(getState(), simple1.id).get("loadedState"));
yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
ok(getSource(getState(), simple1.id).get("text"));
assertHighlightLocation(dbg, "simple1.js", 6);

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

@ -20,6 +20,16 @@ function getValue(dbg, index) {
return findElement(dbg, "expressionValue", index).innerText;
}
function assertEmptyValue(dbg, index) {
const value = findElement(dbg, "expressionValue", index);
if (value) {
is(value.innerText, "");
return;
}
is(value, null);
}
function toggleExpression(dbg, index) {
findElement(dbg, "expressionNode", index).click();
}
@ -55,8 +65,9 @@ add_task(function*() {
yield editExpression(dbg, "oo");
is(getLabel(dbg, 1), "foo()");
// There is no "value" element for functions.
is(findElement(dbg, "expressionValue", 1), null);
assertEmptyValue(dbg, 1);
yield addExpression(dbg, "location");
is(getLabel(dbg, 2), "location");
@ -68,5 +79,6 @@ add_task(function*() {
yield deleteExpression(dbg, "foo");
yield deleteExpression(dbg, "location");
is(findAllElements(dbg, "expressionNodes").length, 0);
});

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

@ -0,0 +1,10 @@
async function thing(inc) {
return new Promise(resolve => {
setTimeout(resolve, 10);
});
}
async function main() {
await thing(1);
await thing(2);
}

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

@ -0,0 +1,13 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Async</title>
<script src="async.js"></script>
</head>
<body>
</body>
</html>

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

@ -38,6 +38,10 @@ Services.scriptloader.loadSubScript(
this
);
var { Toolbox } = require("devtools/client/framework/toolbox");
const sourceUtils = {
isLoaded: source => source.get("loadedState") === "loaded"
};
const EXAMPLE_URL =
"http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
@ -214,7 +218,8 @@ function waitForElement(dbg, selector) {
function waitForSelectedSource(dbg, sourceId) {
return waitForState(dbg, state => {
const source = dbg.selectors.getSelectedSource(state);
const isLoaded = source && source.has("loading") && !source.get("loading");
const isLoaded =
source && source.has("loadedState") && sourceUtils.isLoaded(source);
if (sourceId) {
return isLoaded && sourceId == source.get("id");
}
@ -240,9 +245,12 @@ function assertPausedLocation(dbg) {
// Check the pause location
const pause = getPause(getState());
const pauseLine = pause && pause.frame && pause.frame.location.line;
assertDebugLine(dbg, pauseLine);
}
function assertDebugLine(dbg, line) {
// Check the debug line
const lineInfo = getCM(dbg).lineInfo(pauseLine - 1);
const lineInfo = getCM(dbg).lineInfo(line - 1);
ok(
lineInfo.wrapClass.includes("debug-line"),
"Line is highlighted as paused"
@ -331,7 +339,7 @@ function isTopFrameSelected(dbg, state) {
return false;
}
const isLoaded = source.has("loading") && !source.get("loading");
const isLoaded = source.has("loadedState") && sourceUtils.isLoaded(source);
if (!isLoaded) {
return false;
}

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

@ -14,6 +14,11 @@
# that collapses the left and right panes in the debugger UI.
collapsePanes=Collapse panes
# LOCALIZATION NOTE (copySource): This is the text that appears in the
# context menu to copy the selected source of file open.
copySource=Copy
copySource.accesskey=y
# LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the
# context menu to copy the source URL of file open.
copySourceUrl=Copy Source Url
@ -52,6 +57,10 @@ stepInTooltip=Step In %S
# button that steps out of a function call.
stepOutTooltip=Step Out %S
# LOCALIZATION NOTE (workersHeader): The text to display in the events
# header.
workersHeader=Workers
# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list
# when there are no workers.
noWorkersText=This page has no workers.
@ -430,6 +439,11 @@ watchExpressions.refreshButton=Refresh
# a mac we use the unicode character.
welcome.search=%S to search for sources
# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's
# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on
# a mac we use the unicode character.
welcome.findInFiles=%S to find in files
# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search
# prompt for searching for files.
sourceSearch.search=Search Sources…

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

@ -38,5 +38,5 @@ pref("devtools.debugger.expressions", "[]");
pref("devtools.debugger.file-search-case-sensitive", false);
pref("devtools.debugger.file-search-whole-word", false);
pref("devtools.debugger.file-search-regex-match", false);
pref("devtools.debugger.features.async-stepping", false);
pref("devtools.debugger.project-text-search-enabled", true);

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

@ -43,14 +43,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1212477
"Get a context using unexisting id should throw"
);
let webgl = anonymousContent.getCanvasContext("canvas-webgl", "webgl");
const normalWebGL = document.createElement('canvas').getContext('webgl');
if (normalWebGL) {
let webgl = anonymousContent.getCanvasContext("canvas-webgl", "webgl");
is(webgl.toString(), "[object WebGLRenderingContext]",
"WebGL Context is returned properly");
is(webgl.canvas, null,
"WebGL context's canvas property is null in anonymous content");
is(webgl.toString(), "[object WebGLRenderingContext]",
"WebGL Context is returned properly");
is(webgl.canvas, null,
"WebGL context's canvas property is null in anonymous content");
}
chromeDocument.removeAnonymousContent(anonymousContent);
</script>
</body>

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

@ -5184,107 +5184,6 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
nsLayoutUtils::DirectDrawInfo drawInfo;
#ifdef USE_SKIA_GPU
if (mRenderingMode == RenderingMode::OpenGLBackendMode &&
mIsSkiaGL &&
!srcSurf &&
aImage.IsHTMLVideoElement() &&
AllowOpenGLCanvas()) {
mozilla::gl::GLContext* gl = gfxPlatform::GetPlatform()->GetSkiaGLGlue()->GetGLContext();
MOZ_ASSERT(gl);
HTMLVideoElement* video = &aImage.GetAsHTMLVideoElement();
if (!video) {
return;
}
if (video->ContainsRestrictedContent()) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
uint16_t readyState;
if (NS_SUCCEEDED(video->GetReadyState(&readyState)) &&
readyState < nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA) {
// still loading, just return
return;
}
// If it doesn't have a principal, just bail
nsCOMPtr<nsIPrincipal> principal = video->GetCurrentVideoPrincipal();
if (!principal) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
mozilla::layers::ImageContainer* container = video->GetImageContainer();
if (!container) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
AutoLockImage lockImage(container);
layers::Image* srcImage = lockImage.GetImage();
if (!srcImage) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
{
if (!gl->MakeCurrent()) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
GLuint videoTexture = 0;
gl->fGenTextures(1, &videoTexture);
// skiaGL expect upload on drawing, and uses texture 0 for texturing,
// so we must active texture 0 and bind the texture for it.
gl->fActiveTexture(LOCAL_GL_TEXTURE0);
const gl::ScopedBindTexture scopeBindTexture(gl, videoTexture);
gl->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGB, srcImage->GetSize().width, srcImage->GetSize().height, 0, LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5, nullptr);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage, srcImage->GetSize(),
videoTexture, LOCAL_GL_TEXTURE_2D,
destOrigin);
if (ok) {
NativeSurface texSurf;
texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
texSurf.mFormat = SurfaceFormat::R5G6B5_UINT16;
texSurf.mSize.width = srcImage->GetSize().width;
texSurf.mSize.height = srcImage->GetSize().height;
texSurf.mSurface = (void*)((uintptr_t)videoTexture);
srcSurf = mTarget->CreateSourceSurfaceFromNativeSurface(texSurf);
if (!srcSurf) {
gl->fDeleteTextures(1, &videoTexture);
}
imgSize.width = srcImage->GetSize().width;
imgSize.height = srcImage->GetSize().height;
int32_t displayWidth = video->VideoWidth();
int32_t displayHeight = video->VideoHeight();
aSw *= (double)imgSize.width / (double)displayWidth;
aSh *= (double)imgSize.height / (double)displayHeight;
} else {
gl->fDeleteTextures(1, &videoTexture);
}
}
srcImage = nullptr;
if (mCanvasElement) {
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
principal, false,
video->GetCORSMode() != CORS_NONE);
}
}
#endif
if (!srcSurf) {
// The canvas spec says that drawImage should draw the first frame
// of animated images. We also don't want to rasterize vector images.

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

@ -639,6 +639,10 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
fallbackReason = "depth is not 1";
break;
}
if (xOffset != 0 || yOffset != 0 || zOffset != 0) {
fallbackReason = "x/y/zOffset is not 0";
break;
}
if (webgl->mPixelStore_UnpackSkipPixels ||
webgl->mPixelStore_UnpackSkipRows ||
@ -701,9 +705,7 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
const gfx::IntSize destSize(mWidth, mHeight);
const auto dstOrigin = (webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
: gl::OriginPos::BottomLeft);
if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, scopedFB.FB(),
dstOrigin))
{
if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, dstOrigin)) {
fallbackReason = "likely bug: failed to blit";
break;
}

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

@ -721,6 +721,12 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
return false;
}
if (!gl->IsSupported(GLFeature::vertex_array_object)) {
*out_failReason = { "FEATURE_FAILURE_WEBGL_VAOS",
"Requires vertex_array_object." };
return false;
}
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mBoundVertexArray = mDefaultVertexArray;

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

@ -1833,8 +1833,11 @@ ScopedCopyTexImageSource::ScopedCopyTexImageSource(WebGLContext* webgl,
// Draw-blit rgbaTex into rgbaFB.
const gfx::IntSize srcSize(srcWidth, srcHeight);
gl->BlitHelper()->DrawBlitTextureToFramebuffer(scopedTex.Texture(), rgbaFB,
srcSize, srcSize);
{
const gl::ScopedBindFramebuffer bindFB(gl, rgbaFB);
gl->BlitHelper()->DrawBlitTextureToFramebuffer(scopedTex.Texture(), srcSize,
srcSize);
}
// Restore Tex2D binding and destroy the temp tex.
scopedBindTex.Unwrap();

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

@ -176,4 +176,4 @@ include filters/reftest.list
== clipped-dash-stroke-rect.html clipped-dash-stroke-rect-ref.html
# Bug 1377303
== visible-occluded.html visible-occluded-ref.html
skip-if(Android) == visible-occluded.html visible-occluded-ref.html

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

@ -50,6 +50,10 @@ function todo(val, text) {
debug(status + text);
}
function addLoadEvent(func) {
window.addEventListener('load', func, false);
}
SimpleTest = {
waitForExplicitFinish: function() {},
finish: function() {},

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

@ -99,13 +99,10 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
[test_fuzzing_bugs.html]
[test_video_fastpath_mp4.html]
fail-if = (os == 'mac') || (os == 'win' && !(e10s && os_version == '6.1')) # no fast path on windows yet (bug 1373165 or 1373770), and mac (bug 1373669)
fail-if = (os == 'win' && os_version == '6.1' && !e10s)
[test_video_fastpath_theora.html]
fail-if = (os == 'win' && os_version != '6.1') # no fast path on windows yet (bug 1373192), and mac (bug 1373702)
[test_video_fastpath_vp8.html]
fail-if = (os == 'win' && os_version != '6.1') # no fast path on windows yet (bug 1373192), and mac (bug 1373702)
[test_video_fastpath_vp9.html]
fail-if = (os == 'win' && os_version != '6.1') # no fast path on windows yet (bug 1373192), and mac (bug 1373702)
[test_webglcontextcreationerror.html]
[test_webgl_fingerprinting_resistance.html]
fail-if = (os == 'mac') || (os == 'win') # on try server, LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE = 512 on mac and LOCAL_GL_ALIASED_LINE_WIDTH_RANGE = [1, 1] on win

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

@ -39,9 +39,12 @@ using namespace gfx;
SurfaceDescriptorGPUVideo
VideoDecoderManagerParent::StoreImage(Image* aImage, TextureClient* aTexture)
{
mImageMap[aTexture->GetSerial()] = aImage;
mTextureMap[aTexture->GetSerial()] = aTexture;
return SurfaceDescriptorGPUVideo(aTexture->GetSerial());
SurfaceDescriptorGPUVideo ret;
aTexture->GPUVideoDesc(&ret);
mImageMap[ret.handle()] = aImage;
mTextureMap[ret.handle()] = aTexture;
return Move(ret);
}
StaticRefPtr<nsIThread> sVideoDecoderManagerThread;

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

@ -199,7 +199,7 @@ VideoDecoderParent::ProcessDecodedData(
video->mDisplay,
texture ? texture->GetSize() : IntSize(),
texture ? mParent->StoreImage(video->mImage, texture)
: SurfaceDescriptorGPUVideo(0),
: SurfaceDescriptorGPUVideo(0, null_t()),
video->mFrameID);
Unused << SendOutput(output);
}

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

@ -188,7 +188,7 @@ CFStringRef MacIOSurfaceLib::GetIOConst(const char* symbole) {
void MacIOSurfaceLib::LoadLibrary() {
if (isLoaded) {
return;
}
}
isLoaded = true;
sIOSurfaceFramework = dlopen(IOSURFACE_FRAMEWORK_PATH,
RTLD_LAZY | RTLD_LOCAL);
@ -278,7 +278,7 @@ void MacIOSurfaceLib::CloseLibrary() {
sCoreVideoFramework = nullptr;
}
MacIOSurface::MacIOSurface(const void* aIOSurfacePtr,
MacIOSurface::MacIOSurface(IOSurfacePtr aIOSurfacePtr,
double aContentsScaleFactor, bool aHasAlpha)
: mIOSurfacePtr(aIOSurfacePtr)
, mContentsScaleFactor(aContentsScaleFactor)
@ -322,10 +322,10 @@ already_AddRefed<MacIOSurface> MacIOSurface::CreateIOSurface(int aWidth, int aHe
::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropHeight,
cfHeight);
::CFRelease(cfHeight);
::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropBytesPerElem,
::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropBytesPerElem,
cfBytesPerElem);
::CFRelease(cfBytesPerElem);
::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropIsGlobal,
::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropIsGlobal,
kCFBooleanTrue);
IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceCreate(props);
@ -348,7 +348,7 @@ already_AddRefed<MacIOSurface> MacIOSurface::CreateIOSurface(int aWidth, int aHe
already_AddRefed<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID,
double aContentsScaleFactor,
bool aHasAlpha) {
bool aHasAlpha) {
if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
return nullptr;
@ -368,11 +368,11 @@ already_AddRefed<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfac
return ioSurface.forget();
}
IOSurfaceID MacIOSurface::GetIOSurfaceID() {
IOSurfaceID MacIOSurface::GetIOSurfaceID() {
return MacIOSurfaceLib::IOSurfaceGetID(mIOSurfacePtr);
}
void* MacIOSurface::GetBaseAddress() {
void* MacIOSurface::GetBaseAddress() {
return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr);
}
@ -510,6 +510,18 @@ MacIOSurface::GetReadFormat()
}
}
CGLError
MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx,
GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLuint plane) const
{
return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx, target, internalFormat, width,
height, format, type, mIOSurfacePtr,
plane);
}
CGLError
MacIOSurface::CGLTexImageIOSurface2D(mozilla::gl::GLContext* aGL,
CGLContextObj ctx,
@ -577,15 +589,9 @@ MacIOSurface::CGLTexImageIOSurface2D(mozilla::gl::GLContext* aGL,
}
}
return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx,
LOCAL_GL_TEXTURE_RECTANGLE_ARB,
internalFormat,
GetDevicePixelWidth(plane),
GetDevicePixelHeight(plane),
format,
type,
mIOSurfacePtr,
plane);
return CGLTexImageIOSurface2D(ctx, LOCAL_GL_TEXTURE_RECTANGLE_ARB, internalFormat,
GetDevicePixelWidth(plane), GetDevicePixelHeight(plane),
format, type, plane);
}
static

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

@ -97,7 +97,7 @@ public:
double aContentsScaleFactor = 1.0,
bool aHasAlpha = true);
explicit MacIOSurface(const void *aIOSurfacePtr,
explicit MacIOSurface(IOSurfacePtr aIOSurfacePtr,
double aContentsScaleFactor = 1.0,
bool aHasAlpha = true);
~MacIOSurface();
@ -130,6 +130,11 @@ public:
CGLContextObj ctxt,
size_t plane,
mozilla::gfx::SurfaceFormat* aOutReadFormat = nullptr);
CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt,
GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLuint plane) const;
already_AddRefed<SourceSurface> GetAsSurface();
CGContextRef CreateIOSurfaceContext();
@ -144,7 +149,7 @@ public:
private:
friend class nsCARenderer;
const void* mIOSurfacePtr;
const IOSurfacePtr mIOSurfacePtr;
double mContentsScaleFactor;
bool mHasAlpha;
};

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

@ -125,7 +125,7 @@ Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl
ASSERT(mPlanes[0].texture != nullptr);
mPlanes[0].texture->bindStream(this);
mConsumerType = ConsumerType::GLTextureRGB;
mPlaneCount = 1;
mPlaneCount = 1;
}
else
{
@ -163,9 +163,9 @@ Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl
Error Stream::createProducerD3D11TextureNV12(const AttributeMap &attributes)
{
ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR);
ASSERT(mConsumerType == ConsumerType::GLTextureYUV);
ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
mConsumerType == ConsumerType::GLTextureYUV);
ASSERT(mProducerType == ProducerType::NoProducer);
ASSERT(mPlaneCount == 2);
mProducerImplementation = mDisplay->getImplementation()->createStreamProducerD3DTextureNV12(
mConsumerType, attributes);
@ -175,6 +175,7 @@ Error Stream::createProducerD3D11TextureNV12(const AttributeMap &attributes)
return Error(EGL_SUCCESS);
}
// Called when the consumer of this stream starts using the stream
Error Stream::consumerAcquire()
{
@ -226,14 +227,14 @@ bool Stream::isConsumerBoundToContext(const gl::Context *context) const
return (context == mContext);
}
Error Stream::validateD3D11NV12Texture(void *texture) const
Error Stream::validateD3D11NV12Texture(void *texture, const AttributeMap &attributes) const
{
ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
mConsumerType == ConsumerType::GLTextureYUV);
ASSERT(mProducerType == ProducerType::D3D11TextureNV12);
ASSERT(mProducerImplementation != nullptr);
return mProducerImplementation->validateD3DNV12Texture(texture);
return mProducerImplementation->validateD3DNV12Texture(texture, attributes);
}
Error Stream::postD3D11NV12Texture(void *texture, const AttributeMap &attributes)

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

@ -95,7 +95,7 @@ class Stream final : angle::NonCopyable
bool isConsumerBoundToContext(const gl::Context *context) const;
// Producer methods
Error validateD3D11NV12Texture(void *texture) const;
Error validateD3D11NV12Texture(void *texture, const AttributeMap &attributes) const;
Error postD3D11NV12Texture(void *texture, const AttributeMap &attributes);
private:

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

@ -23,7 +23,7 @@ class StreamProducerImpl : angle::NonCopyable
// Validates the ability for the producer to accept an arbitrary pointer to a frame. All
// pointers should be validated through this function before being used to produce a frame.
virtual egl::Error validateD3DNV12Texture(void *pointer) const = 0;
virtual egl::Error validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const = 0;
// Constructs a frame from an arbitrary external pointer that points to producer specific frame
// data. Replaces the internal frame with the new one.

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

@ -15,8 +15,83 @@
namespace rx
{
static egl::Stream::GLTextureDescription getGLDescFromTex(ID3D11Texture2D* tex,
UINT planeIndex,
const char** const out_error)
{
*out_error = "Undocumented error";
egl::Stream::GLTextureDescription ret = { 0 };
if (!tex)
{
*out_error = "Texture is null";
return ret;
}
D3D11_TEXTURE2D_DESC desc;
tex->GetDesc(&desc);
if (desc.Width < 1 || desc.Height < 1)
{
*out_error = "Width or height < 1";
return ret;
}
ret.width = desc.Width;
ret.height = desc.Height;
ret.mipLevels = 0;
UINT maxPlaneIndex = 0;
switch (desc.Format) {
case DXGI_FORMAT_NV12:
// The UV plane of NV12 textures has half the width/height of the Y plane
if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
{
*out_error = "NV12 tetxures must have even width and height.";
break; // Bad width/height.
}
maxPlaneIndex = 1;
if (planeIndex == 0)
{
ret.internalFormat = GL_R8;
}
else
{
ret.internalFormat = GL_RG8;
ret.width /= 2;
ret.height /= 2;
}
break;
case DXGI_FORMAT_R8_UNORM:
ret.internalFormat = GL_R8;
break;
case DXGI_FORMAT_R8G8_UNORM:
ret.internalFormat = GL_RG8;
break;
case DXGI_FORMAT_R8G8B8A8_UNORM:
ret.internalFormat = GL_RGBA8;
break;
default:
*out_error = "Unsupported format";
return ret;
}
if (planeIndex > maxPlaneIndex)
{
// Just kidding, there's no plane out there.
ret.internalFormat = 0;
*out_error = "Plane out of range";
}
return ret;
}
StreamProducerNV12::StreamProducerNV12(Renderer11 *renderer)
: mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mTextureWidth(0), mTextureHeight(0)
: mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0)
{
}
@ -25,7 +100,7 @@ StreamProducerNV12::~StreamProducerNV12()
SafeRelease(mTexture);
}
egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer) const
egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const
{
ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
@ -37,21 +112,14 @@ egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer) const
return egl::Error(EGL_BAD_PARAMETER, "Texture not created on ANGLE D3D device");
}
// Get the description and validate it
D3D11_TEXTURE2D_DESC desc;
textureD3D->GetDesc(&desc);
if (desc.Format != DXGI_FORMAT_NV12)
const auto planeId = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
const char* errorText;
const auto glDesc = getGLDescFromTex(textureD3D, planeId, &errorText);
if (!glDesc.internalFormat)
{
return egl::Error(EGL_BAD_PARAMETER, "Texture format not DXGI_FORMAT_NV12");
}
if (desc.Width < 1 || desc.Height < 1)
{
return egl::Error(EGL_BAD_PARAMETER, "Texture is of size 0");
}
if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
{
return egl::Error(EGL_BAD_PARAMETER, "Texture dimensions are not even");
return egl::Error(EGL_BAD_PARAMETER, errorText);
}
return egl::Error(EGL_SUCCESS);
}
@ -60,33 +128,20 @@ void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeM
ASSERT(pointer != nullptr);
ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
// Check that the texture originated from our device
ID3D11Device *device;
textureD3D->GetDevice(&device);
// Get the description
D3D11_TEXTURE2D_DESC desc;
textureD3D->GetDesc(&desc);
// Release the previous texture if there is one
SafeRelease(mTexture);
mTexture = textureD3D;
mTexture->AddRef();
mTextureWidth = desc.Width;
mTextureHeight = desc.Height;
mArraySlice = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
mPlaneOffset = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
mArraySlice = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
}
egl::Stream::GLTextureDescription StreamProducerNV12::getGLFrameDescription(int planeIndex)
{
// The UV plane of NV12 textures has half the width/height of the Y plane
egl::Stream::GLTextureDescription desc;
desc.width = (planeIndex == 0) ? mTextureWidth : (mTextureWidth / 2);
desc.height = (planeIndex == 0) ? mTextureHeight : (mTextureHeight / 2);
desc.internalFormat = (planeIndex == 0) ? GL_R8 : GL_RG8;
desc.mipLevels = 0;
return desc;
const char* errorText;
return getGLDescFromTex(mTexture, static_cast<UINT>(planeIndex + mPlaneOffset),
&errorText);
}
ID3D11Texture2D *StreamProducerNV12::getD3DTexture()

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

@ -21,7 +21,7 @@ class StreamProducerNV12 : public StreamProducerImpl
StreamProducerNV12(Renderer11 *renderer);
~StreamProducerNV12() override;
egl::Error validateD3DNV12Texture(void *pointer) const override;
egl::Error validateD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) const override;
void postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) override;
egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override;
@ -36,8 +36,7 @@ class StreamProducerNV12 : public StreamProducerImpl
ID3D11Texture2D *mTexture;
UINT mArraySlice;
UINT mTextureWidth;
UINT mTextureHeight;
UINT mPlaneOffset;
};
} // namespace rx

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

@ -1515,9 +1515,22 @@ Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display,
return Error(EGL_BAD_STATE_KHR, "Stream not in connecting state");
}
if (stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV ||
stream->getPlaneCount() != 2)
{
switch (stream->getConsumerType()) {
case Stream::ConsumerType::GLTextureYUV:
if (stream->getPlaneCount() != 2)
{
return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
}
break;
case Stream::ConsumerType::GLTextureRGB:
if (stream->getPlaneCount() != 1)
{
return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
}
break;
default:
return Error(EGL_BAD_MATCH, "Incompatible stream consumer type");
}
@ -1552,6 +1565,12 @@ Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
return Error(EGL_BAD_PARAMETER, "Invalid subresource index");
}
break;
case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG:
if (value < 0)
{
return Error(EGL_BAD_PARAMETER, "Invalid plane offset");
}
break;
default:
return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute");
}
@ -1574,7 +1593,7 @@ Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display,
return egl::Error(EGL_BAD_PARAMETER, "Texture is null");
}
return stream->validateD3D11NV12Texture(texture);
return stream->validateD3D11NV12Texture(texture, attribs);
}
Error ValidateSwapBuffersWithDamageEXT(const Display *display,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -10,154 +10,196 @@
#include "GLContextTypes.h"
#include "GLConsts.h"
#include "nsSize.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/gfx/Point.h"
#include "../layers/ImageTypes.h"
#ifdef XP_WIN
#include <windows.h>
#endif
namespace mozilla {
namespace layers {
class D3D11YCbCrImage;
class Image;
class GPUVideoImage;
class PlanarYCbCrImage;
class SurfaceTextureImage;
class MacIOSurfaceImage;
class EGLImageImage;
class SurfaceDescriptorD3D10;
class SurfaceDescriptorDXGIYCbCr;
} // namespace layers
namespace gl {
class BindAnglePlanes;
class GLContext;
bool
GuessDivisors(const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
gfx::IntSize* const out_divisors);
class DrawBlitProg final
{
const GLBlitHelper& mParent;
const GLuint mProg;
const GLint mLoc_u1ForYFlip;
const GLint mLoc_uSrcRect;
const GLint mLoc_uTexSize0;
const GLint mLoc_uTexSize1;
const GLint mLoc_uDivisors;
const GLint mLoc_uColorMatrix;
public:
struct Key final {
const char* fragHeader;
const char* fragBody;
bool operator <(const Key& x) const {
if (fragHeader != x.fragHeader)
return fragHeader < x.fragHeader;
return fragBody < x.fragBody;
}
};
DrawBlitProg(const GLBlitHelper* parent, GLuint prog);
~DrawBlitProg();
struct BaseArgs final {
gfx::IntSize destSize;
bool yFlip;
gfx::IntRect srcRect;
gfx::IntSize texSize0;
};
struct YUVArgs final {
gfx::IntSize texSize1;
gfx::IntSize divisors;
YUVColorSpace colorSpace;
};
void Draw(const BaseArgs& args, const YUVArgs* argsYUV = nullptr) const;
};
class ScopedSaveMultiTex final
{
GLContext& mGL;
const uint8_t mTexCount;
const GLenum mTexTarget;
const GLuint mOldTexUnit;
GLuint mOldTexSampler[3];
GLuint mOldTex[3];
public:
ScopedSaveMultiTex(GLContext* gl, uint8_t texCount, GLenum texTarget);
~ScopedSaveMultiTex();
};
/** Buffer blitting helper */
class GLBlitHelper final
{
enum Channel
{
Channel_Y = 0,
Channel_Cb,
Channel_Cr,
Channel_Max,
};
friend class BindAnglePlanes;
friend class DrawBlitProg;
friend class GLContext;
/**
* BlitTex2D is used to copy blit the content of a GL_TEXTURE_2D object,
* BlitTexRect is used to copy blit the content of a GL_TEXTURE_RECT object,
* The difference between BlitTex2D and BlitTexRect is the texture type, which affect
* the fragment shader a bit.
*
* ConvertPlnarYcbCr is used to color convert copy blit the PlanarYCbCrImage
* into a normal RGB texture by create textures of each color channel, and
* convert it in GPU.
* Convert type is created for canvas.
*/
enum BlitType
{
BlitTex2D,
BlitTexRect,
ConvertPlanarYCbCr,
ConvertSurfaceTexture,
ConvertEGLImage,
ConvertMacIOSurfaceImage
};
// The GLContext is the sole owner of the GLBlitHelper.
GLContext* mGL;
GLContext* const mGL;
mutable std::map<DrawBlitProg::Key, const DrawBlitProg*> mDrawBlitProgs;
GLuint mTexBlit_Buffer;
GLuint mTexBlit_VertShader;
GLuint mTex2DBlit_FragShader;
GLuint mTex2DRectBlit_FragShader;
GLuint mTex2DBlit_Program;
GLuint mTex2DRectBlit_Program;
GLuint mQuadVAO;
nsCString mDrawBlitProg_VersionLine;
const GLuint mDrawBlitProg_VertShader;
GLint mYFlipLoc;
GLuint mYuvUploads[3];
gfx::IntSize mYuvUploads_YSize;
gfx::IntSize mYuvUploads_UVSize;
GLint mTextureTransformLoc;
#ifdef XP_WIN
mutable RefPtr<ID3D11Device> mD3D11;
// Data for image blit path
GLuint mTexExternalBlit_FragShader;
GLuint mTexYUVPlanarBlit_FragShader;
GLuint mTexNV12PlanarBlit_FragShader;
GLuint mTexExternalBlit_Program;
GLuint mTexYUVPlanarBlit_Program;
GLuint mTexNV12PlanarBlit_Program;
GLuint mFBO;
GLuint mSrcTexY;
GLuint mSrcTexCb;
GLuint mSrcTexCr;
GLuint mSrcTexEGL;
GLint mYTexScaleLoc;
GLint mCbCrTexScaleLoc;
GLint mYuvColorMatrixLoc;
int mTexWidth;
int mTexHeight;
ID3D11Device* GetD3D11() const;
#endif
// Cache some uniform values
float mCurYScale;
float mCurCbCrScale;
const DrawBlitProg* GetDrawBlitProg(const DrawBlitProg::Key& key) const;
private:
const DrawBlitProg* CreateDrawBlitProg(const DrawBlitProg::Key& key) const;
public:
void UseBlitProgram();
void SetBlitFramebufferForDestTexture(GLuint aTexture);
bool UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize);
bool InitTexQuadProgram(BlitType target = BlitTex2D);
void DeleteTexBlitProgram();
void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
void BindAndUploadEGLImage(EGLImage image, GLuint target);
bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage);
bool BlitImage(layers::PlanarYCbCrImage* yuvImage, const gfx::IntSize& destSize,
OriginPos destOrigin);
#ifdef MOZ_WIDGET_ANDROID
// Blit onto the current FB.
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
bool BlitEGLImageImage(layers::EGLImageImage* eglImage);
bool BlitImage(layers::SurfaceTextureImage* stImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
bool BlitImage(layers::EGLImageImage* eglImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
#endif
#ifdef XP_MACOSX
bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
bool BlitImage(layers::MacIOSurfaceImage* srcImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
#endif
explicit GLBlitHelper(GLContext* gl);
friend class GLContext;
public:
~GLBlitHelper();
// If you don't have |srcFormats| for the 2nd definition,
// then you'll need the framebuffer_blit extensions to use
// the first BlitFramebufferToFramebuffer.
void BlitFramebuffer(const gfx::IntSize& srcSize,
const gfx::IntSize& destSize) const;
void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
bool internalFBs = false);
void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
const GLFormats& srcFormats,
bool internalFBs = false);
void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize) const;
void BlitFramebufferToTexture(GLuint destTex, const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
bool internalFBs = false);
void DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
bool internalFBs = false);
void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
const gfx::IntSize& srcSize,
GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
void BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum destTarget = LOCAL_GL_TEXTURE_2D,
bool internalFBs = false);
GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
GLenum destTarget = LOCAL_GL_TEXTURE_2D);
GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
void DrawBlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
GLuint destFB, OriginPos destOrigin);
bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
GLuint destTex, GLenum destTarget, OriginPos destOrigin);
OriginPos destOrigin);
private:
#ifdef XP_WIN
// GLBlitHelperD3D.cpp:
bool BlitImage(layers::GPUVideoImage* srcImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
bool BlitImage(layers::D3D11YCbCrImage* srcImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
bool BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
const gfx::IntSize& destSize, OriginPos destOrigin) const;
bool BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
const gfx::IntRect& clipRect,
const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
const YUVColorSpace colorSpace,
const gfx::IntSize& destSize, OriginPos destOrigin) const;
bool BlitAnglePlanes(uint8_t numPlanes, const RefPtr<ID3D11Texture2D>* texD3DList,
const DrawBlitProg* prog, const DrawBlitProg::BaseArgs& baseArgs,
const DrawBlitProg::YUVArgs* const yuvArgs) const;
#endif
};
extern const char* const kFragHeader_Tex2D;
extern const char* const kFragHeader_Tex2DRect;
extern const char* const kFragHeader_TexExt;
extern const char* const kFragBody_RGBA;
extern const char* const kFragBody_CrYCb;
extern const char* const kFragBody_NV12;
extern const char* const kFragBody_PlanarYUV;
} // namespace gl
} // namespace mozilla

334
gfx/gl/GLBlitHelperD3D.cpp Normal file
Просмотреть файл

@ -0,0 +1,334 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GLBlitHelper.h"
#include <d3d11.h>
#include "GLContext.h"
#include "GLLibraryEGL.h"
#include "GPUVideoImage.h"
#include "ScopedGLHelpers.h"
#include "mozilla/layers/D3D11YCbCrImage.h"
#include "mozilla/layers/TextureD3D11.h"
namespace mozilla {
namespace gl {
static EGLStreamKHR
StreamFromD3DTexture(ID3D11Texture2D* const texD3D,
const EGLAttrib* const postAttribs)
{
auto& egl = sEGLLibrary;
const auto& display = egl.Display();
const auto stream = egl.fCreateStreamKHR(display, nullptr);
MOZ_ASSERT(stream);
if (!stream)
return 0;
bool ok = true;
MOZ_ALWAYS_TRUE( ok &= bool(egl.fStreamConsumerGLTextureExternalAttribsNV(display,
stream,
nullptr)) );
MOZ_ALWAYS_TRUE( ok &= bool(egl.fCreateStreamProducerD3DTextureNV12ANGLE(display,
stream,
nullptr)) );
MOZ_ALWAYS_TRUE( ok &= bool(egl.fStreamPostD3DTextureNV12ANGLE(display, stream,
texD3D,
postAttribs)) );
if (ok)
return stream;
(void)egl.fDestroyStreamKHR(display, stream);
return 0;
}
static RefPtr<ID3D11Texture2D>
OpenSharedTexture(ID3D11Device* const d3d, const WindowsHandle handle)
{
RefPtr<ID3D11Texture2D> tex;
auto hr = d3d->OpenSharedResource((HANDLE)handle, __uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(tex));
if (FAILED(hr)) {
MOZ_ASSERT(false, "OpenSharedResource should not fail");
return nullptr;
}
return tex;
}
// -------------------------------------
class BindAnglePlanes final
{
const GLBlitHelper& mParent;
const uint8_t mNumPlanes;
const ScopedSaveMultiTex mMultiTex;
GLuint mTempTexs[3];
EGLStreamKHR mStreams[3];
RefPtr<IDXGIKeyedMutex> mMutexList[3];
bool mSuccess;
public:
BindAnglePlanes(const GLBlitHelper* const parent, const uint8_t numPlanes,
const RefPtr<ID3D11Texture2D>* const texD3DList,
const EGLAttrib* const* postAttribsList = nullptr)
: mParent(*parent)
, mNumPlanes(numPlanes)
, mMultiTex(mParent.mGL, mNumPlanes, LOCAL_GL_TEXTURE_EXTERNAL)
, mTempTexs{0}
, mStreams{0}
, mSuccess(true)
{
MOZ_RELEASE_ASSERT(numPlanes >= 1 && numPlanes <= 3);
const auto& gl = mParent.mGL;
auto& egl = sEGLLibrary;
const auto& display = egl.Display();
gl->fGenTextures(numPlanes, mTempTexs);
for (uint8_t i = 0; i < mNumPlanes; i++) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
gl->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, mTempTexs[i]);
const EGLAttrib* postAttribs = nullptr;
if (postAttribsList) {
postAttribs = postAttribsList[i];
}
mStreams[i] = StreamFromD3DTexture(texD3DList[i], postAttribs);
mSuccess &= bool(mStreams[i]);
}
if (mSuccess) {
for (uint8_t i = 0; i < mNumPlanes; i++) {
MOZ_ALWAYS_TRUE( egl.fStreamConsumerAcquireKHR(display, mStreams[i]) );
auto& mutex = mMutexList[i];
texD3DList[i]->QueryInterface(_uuidof(IDXGIKeyedMutex),
(void**)getter_AddRefs(mutex));
if (mutex) {
const auto hr = mutex->AcquireSync(0, 100);
if (FAILED(hr)) {
NS_WARNING("BindAnglePlanes failed to acquire KeyedMutex.");
mSuccess = false;
}
}
}
}
}
~BindAnglePlanes()
{
const auto& gl = mParent.mGL;
auto& egl = sEGLLibrary;
const auto& display = egl.Display();
if (mSuccess) {
for (uint8_t i = 0; i < mNumPlanes; i++) {
MOZ_ALWAYS_TRUE( egl.fStreamConsumerReleaseKHR(display, mStreams[i]) );
if (mMutexList[i]) {
mMutexList[i]->ReleaseSync(0);
}
}
}
for (uint8_t i = 0; i < mNumPlanes; i++) {
(void)egl.fDestroyStreamKHR(display, mStreams[i]);
}
gl->fDeleteTextures(mNumPlanes, mTempTexs);
}
const bool& Success() const { return mSuccess; }
};
// -------------------------------------
ID3D11Device*
GLBlitHelper::GetD3D11() const
{
if (mD3D11)
return mD3D11;
if (!mGL->IsANGLE())
return nullptr;
auto& egl = sEGLLibrary;
EGLDeviceEXT deviceEGL = 0;
MOZ_ALWAYS_TRUE( egl.fQueryDisplayAttribEXT(egl.Display(), LOCAL_EGL_DEVICE_EXT,
(EGLAttrib*)&deviceEGL) );
if (!egl.fQueryDeviceAttribEXT(deviceEGL, LOCAL_EGL_D3D11_DEVICE_ANGLE,
(EGLAttrib*)(ID3D11Device**)getter_AddRefs(mD3D11)))
{
MOZ_ASSERT(false, "d3d9?");
return nullptr;
}
return mD3D11;
}
// -------------------------------------
bool
GLBlitHelper::BlitImage(layers::GPUVideoImage* const srcImage,
const gfx::IntSize& destSize, const OriginPos destOrigin) const
{
const auto& data = srcImage->GetData();
if (!data)
return false;
const auto& desc = data->SD();
const auto& subdescUnion = desc.subdesc();
switch (subdescUnion.type()) {
case subdescUnion.TSurfaceDescriptorD3D10:
{
const auto& subdesc = subdescUnion.get_SurfaceDescriptorD3D10();
return BlitDescriptor(subdesc, destSize, destOrigin);
}
case subdescUnion.TSurfaceDescriptorDXGIYCbCr:
{
const auto& subdesc = subdescUnion.get_SurfaceDescriptorDXGIYCbCr();
const auto& clipSize = subdesc.size();
const auto& ySize = subdesc.sizeY();
const auto& uvSize = subdesc.sizeCbCr();
const gfx::IntRect clipRect(0, 0, clipSize.width, clipSize.height);
const auto colorSpace = YUVColorSpace::BT601;
const WindowsHandle handles[3] = {
subdesc.handleY(),
subdesc.handleCb(),
subdesc.handleCr()
};
return BlitAngleYCbCr(handles, clipRect, ySize, uvSize, colorSpace, destSize,
destOrigin);
}
default:
gfxCriticalError() << "Unhandled subdesc type: " << uint32_t(subdescUnion.type());
return false;
}
}
// -------------------------------------
bool
GLBlitHelper::BlitImage(layers::D3D11YCbCrImage* const srcImage,
const gfx::IntSize& destSize, const OriginPos destOrigin) const
{
const auto& data = srcImage->GetData();
if (!data)
return false;
const auto& clipRect = srcImage->mPictureRect;
const auto& colorSpace = srcImage->mColorSpace;
const WindowsHandle handles[3] = {
(WindowsHandle)data->mHandles[0],
(WindowsHandle)data->mHandles[1],
(WindowsHandle)data->mHandles[2]
};
return BlitAngleYCbCr(handles, srcImage->mPictureRect, srcImage->mYSize,
srcImage->mCbCrSize, srcImage->mColorSpace, destSize,
destOrigin);
}
// -------------------------------------
bool
GLBlitHelper::BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
const gfx::IntSize& destSize, OriginPos destOrigin) const
{
const auto& d3d = GetD3D11();
if (!d3d)
return false;
const auto& handle = desc.handle();
const auto& format = desc.format();
const auto& clipSize = desc.size();
const auto srcOrigin = OriginPos::BottomLeft;
const gfx::IntRect clipRect(0, 0, clipSize.width, clipSize.height);
const auto colorSpace = YUVColorSpace::BT601;
if (format != gfx::SurfaceFormat::NV12) {
gfxCriticalError() << "Non-NV12 format for SurfaceDescriptorD3D10: "
<< uint32_t(format);
return nullptr;
}
const auto tex = OpenSharedTexture(d3d, handle);
const RefPtr<ID3D11Texture2D> texList[2] = { tex, tex };
const EGLAttrib postAttribs0[] = {
LOCAL_EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0,
LOCAL_EGL_NONE
};
const EGLAttrib postAttribs1[] = {
LOCAL_EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 1,
LOCAL_EGL_NONE
};
const EGLAttrib* const postAttribsList[2] = { postAttribs0, postAttribs1 };
// /layers/d3d11/CompositorD3D11.cpp uses bt601 for EffectTypes::NV12.
//return BlitAngleNv12(tex, YUVColorSpace::BT601, destSize, destOrigin);
const BindAnglePlanes bindPlanes(this, 2, texList, postAttribsList);
D3D11_TEXTURE2D_DESC texDesc = {0};
tex->GetDesc(&texDesc);
const gfx::IntSize ySize(texDesc.Width, texDesc.Height);
const gfx::IntSize divisors(2, 2);
MOZ_ASSERT(ySize.width % divisors.width == 0);
MOZ_ASSERT(ySize.height % divisors.height == 0);
const gfx::IntSize uvSize(ySize.width / divisors.width,
ySize.height / divisors.height);
const bool yFlip = destOrigin != srcOrigin;
const DrawBlitProg::BaseArgs baseArgs = { destSize, yFlip, clipRect, ySize };
const DrawBlitProg::YUVArgs yuvArgs = { uvSize, divisors, colorSpace };
const auto& prog = GetDrawBlitProg({kFragHeader_TexExt, kFragBody_NV12});
MOZ_RELEASE_ASSERT(prog);
prog->Draw(baseArgs, &yuvArgs);
return true;
}
// --
bool
GLBlitHelper::BlitAngleYCbCr(const WindowsHandle (&handleList)[3],
const gfx::IntRect& clipRect,
const gfx::IntSize& ySize, const gfx::IntSize& uvSize,
const YUVColorSpace colorSpace,
const gfx::IntSize& destSize, OriginPos destOrigin) const
{
const auto& d3d = GetD3D11();
if (!d3d)
return false;
const auto srcOrigin = OriginPos::BottomLeft;
gfx::IntSize divisors;
if (!GuessDivisors(ySize, uvSize, &divisors))
return false;
const RefPtr<ID3D11Texture2D> texList[3] = {
OpenSharedTexture(d3d, handleList[0]),
OpenSharedTexture(d3d, handleList[1]),
OpenSharedTexture(d3d, handleList[2])
};
const BindAnglePlanes bindPlanes(this, 3, texList);
const bool yFlip = destOrigin != srcOrigin;
const DrawBlitProg::BaseArgs baseArgs = { destSize, yFlip, clipRect, ySize };
const DrawBlitProg::YUVArgs yuvArgs = { uvSize, divisors, colorSpace };
const auto& prog = GetDrawBlitProg({kFragHeader_TexExt, kFragBody_PlanarYUV});
MOZ_RELEASE_ASSERT(prog);
prog->Draw(baseArgs, &yuvArgs);
return true;
}
} // namespace gl
} // namespace mozilla

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

@ -1417,6 +1417,22 @@ public:
return retval;
}
void SetEnabled(const GLenum cap, const bool val) {
if (val) {
fEnable(cap);
} else {
fDisable(cap);
}
}
bool PushEnabled(const GLenum cap, const bool newVal) {
const bool oldVal = fIsEnabled(cap);
if (oldVal != newVal) {
SetEnabled(cap, newVal);
}
return oldVal;
}
realGLboolean fIsProgram(GLuint program) {
BEFORE_GL_CALL;
realGLboolean retval = mSymbols.fIsProgram(program);

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

@ -114,7 +114,7 @@ protected:
friend class GLContextEGLFactory;
public:
const EGLConfig mConfig;
const EGLConfig mConfig;
protected:
EGLSurface mSurface;
public:

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

@ -610,6 +610,7 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId
if (IsExtensionSupported(KHR_stream_consumer_gltexture)) {
const GLLibraryLoader::SymLoadStruct streamConsumerSymbols[] = {
SYMBOL(StreamConsumerGLTextureExternalKHR),
SYMBOL(StreamConsumerAcquireKHR),
SYMBOL(StreamConsumerReleaseKHR),
END_OF_SYMBOLS

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

@ -300,6 +300,9 @@ public:
WRAP( fQueryStreamKHR(dpy, stream, attribute, value) )
// KHR_stream_consumer_gltexture
EGLBoolean fStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) const
WRAP( fStreamConsumerGLTextureExternalKHR(dpy, stream) )
EGLBoolean fStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) const
WRAP( fStreamConsumerAcquireKHR(dpy, stream) )
@ -467,6 +470,8 @@ private:
EGLenum attribute,
EGLint* value);
// KHR_stream_consumer_gltexture
EGLBoolean (GLAPIENTRY * fStreamConsumerGLTextureExternalKHR)(EGLDisplay dpy,
EGLStreamKHR stream);
EGLBoolean (GLAPIENTRY * fStreamConsumerAcquireKHR)(EGLDisplay dpy,
EGLStreamKHR stream);
EGLBoolean (GLAPIENTRY * fStreamConsumerReleaseKHR)(EGLDisplay dpy,

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

@ -23,7 +23,7 @@ class HeapCopyOfStackArray
{
public:
template<size_t N>
MOZ_IMPLICIT HeapCopyOfStackArray(ElemType (&array)[N])
MOZ_IMPLICIT HeapCopyOfStackArray(const ElemType (&array)[N])
: mArrayLength(N)
, mArrayData(MakeUnique<ElemType[]>(N))
{

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

@ -423,75 +423,6 @@ ScopedVertexAttribPointer::UnwrapImpl()
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundBuffer);
}
ScopedGLDrawState::ScopedGLDrawState(GLContext* aGL)
: blend (aGL, LOCAL_GL_BLEND, false)
, cullFace (aGL, LOCAL_GL_CULL_FACE, false)
, depthTest (aGL, LOCAL_GL_DEPTH_TEST, false)
, dither (aGL, LOCAL_GL_DITHER, false)
, polyOffsFill(aGL, LOCAL_GL_POLYGON_OFFSET_FILL, false)
, sampleAToC (aGL, LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE, false)
, sampleCover (aGL, LOCAL_GL_SAMPLE_COVERAGE, false)
, scissor (aGL, LOCAL_GL_SCISSOR_TEST, false)
, stencil (aGL, LOCAL_GL_STENCIL_TEST, false)
, mGL(aGL)
{
mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, &boundProgram);
mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &boundBuffer);
mGL->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &maxAttrib);
attrib_enabled = MakeUnique<GLint[]>(maxAttrib);
for (GLuint i = 0; i < maxAttrib; i++) {
mGL->fGetVertexAttribiv(i, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled[i]);
mGL->fDisableVertexAttribArray(i);
}
// Only Attrib0's client side state affected
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib0_size);
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib0_stride);
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib0_type);
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib0_normalized);
mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &attrib0_bufferBinding);
mGL->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib0_pointer);
mGL->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorMask);
mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, scissorBox);
}
ScopedGLDrawState::~ScopedGLDrawState()
{
MOZ_ASSERT(mGL->IsCurrent());
mGL->fScissor(scissorBox[0], scissorBox[1],
scissorBox[2], scissorBox[3]);
mGL->fViewport(viewport[0], viewport[1],
viewport[2], viewport[3]);
mGL->fColorMask(colorMask[0],
colorMask[1],
colorMask[2],
colorMask[3]);
for (unsigned int i = 0; i < maxAttrib; i++) {
if (attrib_enabled[i])
mGL->fEnableVertexAttribArray(i);
else
mGL->fDisableVertexAttribArray(i);
}
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0_bufferBinding);
mGL->fVertexAttribPointer(0,
attrib0_size,
attrib0_type,
attrib0_normalized,
attrib0_stride,
attrib0_pointer);
mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, boundBuffer);
mGL->fUseProgram(boundProgram);
}
////////////////////////////////////////////////////////////////////////
// ScopedPackState

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

@ -122,7 +122,9 @@ protected:
public:
explicit ScopedTexture(GLContext* aGL);
GLuint Texture() { return mTexture; }
GLuint Texture() const { return mTexture; }
operator GLuint() const { return mTexture; }
protected:
void UnwrapImpl();
@ -309,39 +311,6 @@ protected:
void UnwrapImpl();
};
struct ScopedGLDrawState
{
explicit ScopedGLDrawState(GLContext* gl);
~ScopedGLDrawState();
GLuint boundProgram;
GLuint boundBuffer;
ScopedGLState blend;
ScopedGLState cullFace;
ScopedGLState depthTest;
ScopedGLState dither;
ScopedGLState polyOffsFill;
ScopedGLState sampleAToC;
ScopedGLState sampleCover;
ScopedGLState scissor;
ScopedGLState stencil;
GLuint maxAttrib;
UniquePtr<GLint[]> attrib_enabled;
GLint attrib0_size;
GLint attrib0_stride;
GLint attrib0_type;
GLint attrib0_normalized;
GLint attrib0_bufferBinding;
void* attrib0_pointer;
realGLboolean colorMask[4];
GLint viewport[4];
GLint scissorBox[4];
GLContext* const mGL;
};
struct ScopedPackState
: public ScopedGLWrapper<ScopedPackState>
{

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

@ -65,11 +65,12 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
GLuint destTex = dest->ProdTexture();
GLenum destTarget = dest->ProdTextureTarget();
gl->BlitHelper()->BlitFramebufferToTexture(0, destTex,
const ScopedBindFramebuffer bindFB(gl, 0);
gl->BlitHelper()->BlitFramebufferToTexture(destTex,
src->mSize,
dest->mSize,
destTarget,
true);
destTarget);
} else if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
GLuint destRB = dest->ProdRenderbuffer();
ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
@ -77,8 +78,7 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
gl->BlitHelper()->BlitFramebufferToFramebuffer(0,
destWrapper.FB(),
src->mSize,
dest->mSize,
true);
dest->mSize);
} else {
MOZ_CRASH("GFX: Unhandled dest->mAttachType 1.");
}
@ -110,11 +110,12 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
GLuint srcTex = src->ProdTexture();
GLenum srcTarget = src->ProdTextureTarget();
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0,
const ScopedBindFramebuffer bindFB(gl, 0);
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex,
src->mSize,
dest->mSize,
srcTarget,
!!gl->Screen());
srcTarget);
} else if (src->mAttachType == AttachmentType::GLRenderbuffer) {
GLuint srcRB = src->ProdRenderbuffer();
ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
@ -122,8 +123,7 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(),
0,
src->mSize,
dest->mSize,
true);
dest->mSize);
} else {
MOZ_CRASH("GFX: Unhandled src->mAttachType 2.");
}
@ -158,9 +158,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
GLuint destRB = dest->ProdRenderbuffer();
ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
src->mSize, dest->mSize, srcTarget);
const ScopedBindFramebuffer bindFB(gl, destWrapper.FB());
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, src->mSize, dest->mSize,
srcTarget);
return;
}
@ -175,9 +175,10 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
if (dest->mAttachType == AttachmentType::GLTexture) {
GLuint destTex = dest->ProdTexture();
GLenum destTarget = dest->ProdTextureTarget();
const ScopedBindFramebuffer bindFB(gl, srcWrapper.FB());
gl->BlitHelper()->BlitFramebufferToTexture(srcWrapper.FB(), destTex,
src->mSize, dest->mSize, destTarget);
gl->BlitHelper()->BlitFramebufferToTexture(destTex, src->mSize, dest->mSize,
destTarget);
return;
}

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

@ -471,8 +471,8 @@ SharedSurface_D3D11Interop::ProducerReleaseImpl()
MOZ_ASSERT(mLockedForGL);
if (mProdTex) {
mGL->BlitHelper()->DrawBlitTextureToFramebuffer(mProdTex, mInteropFB, mSize,
mSize);
const ScopedBindFramebuffer bindFB(mGL, mInteropFB);
mGL->BlitHelper()->DrawBlitTextureToFramebuffer(mProdTex, mSize, mSize);
}
if (mNeedsFinish) {

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

@ -69,6 +69,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'WGLLibrary.h',
]
UNIFIED_SOURCES += [
'GLBlitHelperD3D.cpp',
'GLContextProviderWGL.cpp',
'SharedSurfaceANGLE.cpp',
'SharedSurfaceD3D11Interop.cpp',

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

@ -97,7 +97,7 @@ D3D11YCbCrImage::SetData(KnowsCompositor* aAllocator,
aData.mCbCrStride,
aData.mCbCrStride * aData.mCbCrSize.height);
return true;
}
@ -113,6 +113,15 @@ D3D11YCbCrImage::GetTextureClient(KnowsCompositor* aForwarder)
return mTextureClient;
}
const DXGIYCbCrTextureData*
D3D11YCbCrImage::GetData() const
{
if (!mTextureClient)
return nullptr;
return static_cast<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData());
}
already_AddRefed<SourceSurface>
D3D11YCbCrImage::GetAsSourceSurface()
{

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

@ -12,10 +12,14 @@
#include "ImageContainer.h"
namespace mozilla {
namespace gl {
class GLBlitHelper;
}
namespace layers {
class ImageContainer;
class DXGIYCbCrTextureClient;
class DXGIYCbCrTextureData;
class D3D11YCbCrRecycleAllocator : public TextureClientRecycleAllocator
{
@ -46,6 +50,7 @@ protected:
class D3D11YCbCrImage : public Image
{
friend class gl::GLBlitHelper;
public:
D3D11YCbCrImage();
virtual ~D3D11YCbCrImage();
@ -65,6 +70,8 @@ public:
gfx::IntRect GetPictureRect() override { return mPictureRect; }
private:
const DXGIYCbCrTextureData* GetData() const;
gfx::IntSize mYSize;
gfx::IntSize mCbCrSize;
gfx::IntRect mPictureRect;

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

@ -78,12 +78,11 @@ GLImage::GetAsSourceSurface()
}
const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
if (!sSnapshotContext->BlitHelper()->BlitImageToFramebuffer(this, size,
autoFBForTex.FB(),
destOrigin))
{
return nullptr;
const ScopedBindFramebuffer bindFB(sSnapshotContext, autoFBForTex.FB());
if (!sSnapshotContext->BlitHelper()->BlitImageToFramebuffer(this, size, destOrigin)) {
return nullptr;
}
}
RefPtr<gfx::DataSourceSurface> source =

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

@ -16,11 +16,15 @@ namespace mozilla {
namespace dom {
class VideoDecoderManagerChild;
}
namespace gl {
class GLBlitHelper;
}
namespace layers {
// Image class that refers to a decoded video frame within
// the GPU process.
class GPUVideoImage final : public Image {
friend class gl::GLBlitHelper;
public:
GPUVideoImage(dom::VideoDecoderManagerChild* aManager,
const SurfaceDescriptorGPUVideo& aSD,
@ -45,12 +49,21 @@ public:
gfx::IntSize GetSize() override { return mSize; }
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override
{
private:
GPUVideoTextureData* GetData() const {
if (!mTextureClient) {
return nullptr;
}
GPUVideoTextureData* data = mTextureClient->GetInternalData()->AsGPUVideoTextureData();
return mTextureClient->GetInternalData()->AsGPUVideoTextureData();
}
public:
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override
{
GPUVideoTextureData* data = GetData();
if (!data) {
return nullptr;
}
return data->GetAsSourceSurface();
}

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

@ -48,6 +48,9 @@ protected:
RefPtr<dom::VideoDecoderManagerChild> mManager;
SurfaceDescriptorGPUVideo mSD;
gfx::IntSize mSize;
public:
const decltype(mSD)& SD() const { return mSD; }
};
} // namespace layers

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

@ -162,7 +162,7 @@ private:
// Lock tile A
// Lock tile B
// Lock tile C
// Apply drawing commands to tiles A, B and C
// Apply drawing commands to tiles A, B and C
// Unlock tile A
// Unlock tile B
// Unlock tile C
@ -1402,6 +1402,18 @@ TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
#endif
}
void
TextureClient::GPUVideoDesc(SurfaceDescriptorGPUVideo* const aOutDesc)
{
const auto handle = GetSerial();
GPUVideoSubDescriptor subDesc = null_t();
MOZ_RELEASE_ASSERT(mData);
mData->GetSubDescriptor(&subDesc);
*aOutDesc = SurfaceDescriptorGPUVideo(handle, Move(subDesc));
}
class MemoryTextureReadLock : public NonBlockingTextureReadLock {
public:
MemoryTextureReadLock();

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

@ -266,6 +266,7 @@ public:
virtual void Forget(LayersIPCChannel* aAllocator) {}
virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) { }
virtual TextureData*
CreateSimilar(LayersIPCChannel* aAllocator,
@ -598,12 +599,13 @@ public:
const TextureData* GetInternalData() const { return mData; }
uint64_t GetSerial() const { return mSerial; }
void GPUVideoDesc(SurfaceDescriptorGPUVideo* aOutDesc);
void CancelWaitForRecycle();
/**
* Set last transaction id of CompositableForwarder.
*
*
* Called when TextureClient has TextureFlags::RECYCLE flag.
* When CompositableForwarder forwards the TextureClient with
* TextureFlags::RECYCLE, it holds TextureClient's ref until host side
@ -642,7 +644,7 @@ public:
private:
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
// Internal helpers for creating texture clients using the actual forwarder instead
// of KnowsCompositor. TextureClientPool uses these to let it cache texture clients
// per-process instead of per ShadowLayerForwarder, but everyone else should
@ -657,7 +659,7 @@ private:
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
static already_AddRefed<TextureClient>
CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
gfx::SurfaceFormat aFormat,

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

@ -373,7 +373,7 @@ D3D11TextureData::SyncWithObject(SyncObjectClient* aSyncObject)
}
bool
DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
DXGITextureData::SerializeSpecific(SurfaceDescriptorD3D10* const aOutDesc)
{
RefPtr<IDXGIResource> resource;
GetDXGIResource((IDXGIResource**)getter_AddRefs(resource));
@ -387,10 +387,31 @@ DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
return false;
}
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
*aOutDesc = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
return true;
}
bool
DXGITextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
SurfaceDescriptorD3D10 desc;
if (!SerializeSpecific(&desc))
return false;
aOutDescriptor = Move(desc);
return true;
}
void
DXGITextureData::GetSubDescriptor(GPUVideoSubDescriptor* const aOutDesc)
{
SurfaceDescriptorD3D10 ret;
if (!SerializeSpecific(&ret))
return;
*aOutDesc = Move(ret);
}
DXGITextureData*
DXGITextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationFlags aFlags)
{
@ -659,16 +680,34 @@ DXGIYCbCrTextureData::FillInfo(TextureData::Info& aInfo) const
aInfo.hasSynchronization = false;
}
bool
DXGIYCbCrTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
void
DXGIYCbCrTextureData::SerializeSpecific(SurfaceDescriptorDXGIYCbCr* const aOutDesc)
{
aOutDescriptor = SurfaceDescriptorDXGIYCbCr(
*aOutDesc = SurfaceDescriptorDXGIYCbCr(
(WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2],
mSize, mSizeY, mSizeCbCr
);
}
bool
DXGIYCbCrTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
SurfaceDescriptorDXGIYCbCr desc;
SerializeSpecific(&desc);
aOutDescriptor = Move(desc);
return true;
}
void
DXGIYCbCrTextureData::GetSubDescriptor(GPUVideoSubDescriptor* const aOutDesc)
{
SurfaceDescriptorDXGIYCbCr desc;
SerializeSpecific(&desc);
*aOutDesc = Move(desc);
}
void
DXGIYCbCrTextureData::Deallocate(LayersIPCChannel*)
{

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

@ -18,6 +18,10 @@
#include <vector>
namespace mozilla {
namespace gl {
class GLBlitHelper;
}
namespace layers {
class MOZ_RAII AutoTextureLock
@ -39,7 +43,9 @@ class DXGITextureData : public TextureData
public:
virtual void FillInfo(TextureData::Info& aInfo) const override;
bool SerializeSpecific(SurfaceDescriptorD3D10* aOutDesc);
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) override;
static DXGITextureData*
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
@ -126,6 +132,7 @@ CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat
class DXGIYCbCrTextureData : public TextureData
{
friend class gl::GLBlitHelper;
public:
static DXGIYCbCrTextureData*
Create(IDirect3DTexture9* aTextureY,
@ -152,7 +159,9 @@ public:
virtual void FillInfo(TextureData::Info& aInfo) const override;
void SerializeSpecific(SurfaceDescriptorDXGIYCbCr* aOutDesc);
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void GetSubDescriptor(GPUVideoSubDescriptor* aOutDesc) override;
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override { return nullptr; }

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

@ -80,8 +80,16 @@ struct SurfaceDescriptorSharedGLTexture {
bool hasAlpha;
};
union GPUVideoSubDescriptor {
SurfaceDescriptorD3D10;
SurfaceDescriptorDXGIYCbCr;
null_t;
};
struct SurfaceDescriptorGPUVideo {
uint64_t handle;
GPUVideoSubDescriptor subdesc;
};
struct RGBDescriptor {

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

@ -1111,47 +1111,29 @@ gfxUtils::EncodeSourceSurface(SourceSurface* aSurface,
aBinaryOrData, aFile, nullptr);
}
/* From Rec601:
[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16]
[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128]
[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128]
For [0,1] instead of [0,255], and to 5 places:
[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275]
[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196]
From Rec709:
[R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16]
[G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128]
[B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128]
For [0,1] instead of [0,255], and to 5 places:
[R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275]
[G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196]
[B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196]
*/
static const float kRec601[9] = {
1.16438f, 0.00000f, 1.59603f,
1.16438f,-0.39176f,-0.81297f,
1.16438f, 2.01723f, 0.00000f,
// https://jdashg.github.io/misc/colors/from-coeffs.html
const float kBT601NarrowYCbCrToRGB_RowMajor[16] = {
1.16438f, 0.00000f, 1.59603f,-0.87420f,
1.16438f,-0.39176f,-0.81297f, 0.53167f,
1.16438f, 2.01723f, 0.00000f,-1.08563f,
0.00000f, 0.00000f, 0.00000f, 1.00000f
};
static const float kRec709[9] = {
1.16438f, 0.00000f, 1.79274f,
1.16438f,-0.21325f,-0.53291f,
1.16438f, 2.11240f, 0.00000f,
const float kBT709NarrowYCbCrToRGB_RowMajor[16] = {
1.16438f, 0.00000f, 1.79274f,-0.97295f,
1.16438f,-0.21325f,-0.53291f, 0.30148f,
1.16438f, 2.11240f, 0.00000f,-1.13340f,
0.00000f, 0.00000f, 0.00000f, 1.00000f
};
/* static */ const float*
gfxUtils::YuvToRgbMatrix4x3RowMajor(YUVColorSpace aYUVColorSpace)
{
#define X(x) { x[0], x[1], x[2], 0.0f, \
x[3], x[4], x[5], 0.0f, \
x[6], x[7], x[8], 0.0f }
#define X(x) { x[0], x[1], x[ 2], 0.0f, \
x[4], x[5], x[ 6], 0.0f, \
x[8], x[9], x[10], 0.0f }
static const float rec601[12] = X(kRec601);
static const float rec709[12] = X(kRec709);
static const float rec601[12] = X(kBT601NarrowYCbCrToRGB_RowMajor);
static const float rec709[12] = X(kBT709NarrowYCbCrToRGB_RowMajor);
#undef X
@ -1169,12 +1151,36 @@ gfxUtils::YuvToRgbMatrix4x3RowMajor(YUVColorSpace aYUVColorSpace)
/* static */ const float*
gfxUtils::YuvToRgbMatrix3x3ColumnMajor(YUVColorSpace aYUVColorSpace)
{
#define X(x) { x[0], x[3], x[6], \
x[1], x[4], x[7], \
x[2], x[5], x[8] }
#define X(x) { x[0], x[4], x[ 8], \
x[1], x[5], x[ 9], \
x[2], x[6], x[10] }
static const float rec601[9] = X(kRec601);
static const float rec709[9] = X(kRec709);
static const float rec601[9] = X(kBT601NarrowYCbCrToRGB_RowMajor);
static const float rec709[9] = X(kBT709NarrowYCbCrToRGB_RowMajor);
#undef X
switch (aYUVColorSpace) {
case YUVColorSpace::BT601:
return rec601;
case YUVColorSpace::BT709:
return rec709;
default: // YUVColorSpace::UNKNOWN
MOZ_ASSERT(false, "unknown aYUVColorSpace");
return rec601;
}
}
/* static */ const float*
gfxUtils::YuvToRgbMatrix4x4ColumnMajor(YUVColorSpace aYUVColorSpace)
{
#define X(x) { x[0], x[4], x[ 8], x[12], \
x[1], x[5], x[ 9], x[13], \
x[2], x[6], x[10], x[14], \
x[3], x[7], x[11], x[15] }
static const float rec601[16] = X(kBT601NarrowYCbCrToRGB_RowMajor);
static const float rec709[16] = X(kBT709NarrowYCbCrToRGB_RowMajor);
#undef X

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

@ -158,6 +158,7 @@ public:
static const float* YuvToRgbMatrix4x3RowMajor(mozilla::YUVColorSpace aYUVColorSpace);
static const float* YuvToRgbMatrix3x3ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace);
static const float* YuvToRgbMatrix4x4ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace);
/**
* Creates a copy of aSurface, but having the SurfaceFormat aFormat.