зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: 47jGmg0qsJV
This commit is contained in:
Коммит
7afb65280a
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче