зеркало из https://github.com/mozilla/gecko-dev.git
Merge from mc
This commit is contained in:
Коммит
13dfc88ae1
|
@ -83,13 +83,9 @@ toolbar[printpreview="true"] {
|
|||
}
|
||||
|
||||
%ifdef MENUBAR_CAN_AUTOHIDE
|
||||
#main-window[inFullscreen] > #titlebar {
|
||||
#main-window[inFullscreen] > #appmenu-button-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#titlebar {
|
||||
-moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
|
||||
}
|
||||
%endif
|
||||
|
||||
toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
|
||||
|
|
|
@ -1320,15 +1320,6 @@ function prepareForStartup() {
|
|||
|
||||
// setup simple gestures support
|
||||
gGestureSupport.init(true);
|
||||
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
// update the visibility of the titlebar buttons after the window is
|
||||
// displayed. (required by theme code.)
|
||||
window.addEventListener("MozAfterPaint", function () {
|
||||
window.removeEventListener("MozAfterPaint", arguments.callee, false);
|
||||
document.getElementById("titlebar-buttonbox").collapsed = false;
|
||||
}, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
|
@ -4769,20 +4760,13 @@ function updateAppButtonDisplay() {
|
|||
window.menubar.visible &&
|
||||
document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
|
||||
|
||||
document.getElementById("titlebar").hidden = !displayAppButton;
|
||||
document.getElementById("appmenu-button-container").hidden = !displayAppButton;
|
||||
|
||||
if (displayAppButton)
|
||||
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
|
||||
else
|
||||
document.documentElement.removeAttribute("chromemargin");
|
||||
}
|
||||
|
||||
function onTitlebarMaxClick() {
|
||||
if (window.windowState == window.STATE_MAXIMIZED)
|
||||
window.restore();
|
||||
else
|
||||
window.maximize();
|
||||
}
|
||||
#endif
|
||||
|
||||
function displaySecurityInfo()
|
||||
|
|
|
@ -437,9 +437,7 @@
|
|||
</popupset>
|
||||
|
||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||
<vbox id="titlebar">
|
||||
<hbox id="titlebar-content">
|
||||
<hbox id="appmenu-button-container" align="start">
|
||||
<hbox id="appmenu-button-container">
|
||||
<button id="appmenu-button"
|
||||
type="menu"
|
||||
label="&brandShortName;"
|
||||
|
@ -579,15 +577,7 @@
|
|||
command="cmd_quitApplication"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</hbox>
|
||||
<spacer id="titlebar-spacer" flex="1"/>
|
||||
<hbox id="titlebar-buttonbox" collapsed="true">
|
||||
<toolbarbutton id="titlebar-min" onclick="window.minimize();"/>
|
||||
<toolbarbutton id="titlebar-max" onclick="onTitlebarMaxClick();"/>
|
||||
<toolbarbutton id="titlebar-close" onclick="window.close();"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
#endif
|
||||
|
||||
<toolbox id="navigator-toolbox"
|
||||
|
|
|
@ -36,6 +36,20 @@ function closeContextMenu() {
|
|||
contextMenu.hidePopup();
|
||||
}
|
||||
|
||||
function executeCopyCommand(command, expectedValue)
|
||||
{
|
||||
// Just execute the command directly rather than simulating a context menu
|
||||
// press to avoid having to deal with its asynchronous nature
|
||||
subwindow.controllers.getControllerForCommand(command).doCommand(command);
|
||||
|
||||
// The easiest way to check the clipboard is to paste the contents into a
|
||||
// textbox
|
||||
input.focus();
|
||||
input.value = "";
|
||||
input.controllers.getControllerForCommand("cmd_paste").doCommand("cmd_paste");
|
||||
is(input.value, expectedValue, "paste for command " + command);
|
||||
}
|
||||
|
||||
function getVisibleMenuItems(aMenu) {
|
||||
var items = [];
|
||||
var accessKeys = {};
|
||||
|
@ -391,6 +405,13 @@ function runTest(testNum) {
|
|||
"spell-add-dictionaries", true], null]);
|
||||
|
||||
closeContextMenu();
|
||||
openContextMenuFor(link); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 15:
|
||||
executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
|
||||
closeContextMenu();
|
||||
|
||||
subwindow.close();
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
|
|
|
@ -21,6 +21,15 @@
|
|||
background: transparent;
|
||||
}
|
||||
|
||||
/* the new titlebar requires this, or content will be clipped at the top of the screen. */
|
||||
#main-window[sizemode="maximized"][chromemargin^="0,"] {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
#main-window[sizemode="normal"][chromemargin^="0,"] {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
#main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
|
||||
-moz-appearance: none;
|
||||
background-color: #556;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
* Blake Ross (blake@cs.stanford.edu)
|
||||
* Pamela Greene (pamg.bugs@gmail.com)
|
||||
* Dão Gottwald (dao@mozilla.com)
|
||||
* Jim Mathies (jmathies@mozilla.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -102,7 +101,21 @@ statusbarpanel#statusbar-display {
|
|||
-moz-padding-start: 0;
|
||||
}
|
||||
|
||||
/* ::::: app menu button ::::: */
|
||||
/* App menu button */
|
||||
|
||||
%ifndef WINSTRIPE_AERO
|
||||
#appmenu-button-container {
|
||||
background: ActiveCaption;
|
||||
}
|
||||
|
||||
#appmenu-button-container:-moz-window-inactive {
|
||||
background: InactiveCaption;
|
||||
}
|
||||
%endif
|
||||
|
||||
#appmenu-button-container {
|
||||
-moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
|
||||
}
|
||||
|
||||
#appmenu-button {
|
||||
-moz-appearance: none;
|
||||
|
@ -157,84 +170,24 @@ statusbarpanel#statusbar-display {
|
|||
color: -moz-menuhovertext;
|
||||
}
|
||||
|
||||
/* ::::: titlebar ::::: */
|
||||
|
||||
#titlebar {
|
||||
-moz-appearance: -moz-window-titlebar;
|
||||
/* we only need to the middle section, hide the edges of the
|
||||
theme background beyond the window frame. */
|
||||
margin-left: -15px;
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
#main-window[sizemode="maximized"] > #titlebar {
|
||||
-moz-appearance: -moz-window-titlebar-maximized;
|
||||
}
|
||||
|
||||
#titlebar-content {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* aesthetic - push the fx button off the top window border */
|
||||
@media not all and (-moz-windows-classic) {
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container {
|
||||
%ifndef WINSTRIPE_AERO
|
||||
margin-top: 1px;
|
||||
%else
|
||||
margin-top: 2px;
|
||||
/* XXX: stop-gap until the button can be drawn in the title bar */
|
||||
%ifdef WINSTRIPE_AERO
|
||||
@media not all and (-moz-windows-compositor) {
|
||||
%endif
|
||||
#main-window[tabsontop="true"] > #appmenu-button-container > #appmenu-button {
|
||||
position: relative !important;
|
||||
margin-bottom: -1.6em !important;
|
||||
}
|
||||
}
|
||||
|
||||
#titlebar-buttonbox {
|
||||
-moz-appearance: -moz-window-button-box;
|
||||
-moz-box-align: start;
|
||||
}
|
||||
|
||||
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox {
|
||||
-moz-appearance: -moz-window-button-box-maximized;
|
||||
}
|
||||
|
||||
/* titlebar command buttons */
|
||||
|
||||
#titlebar-min {
|
||||
-moz-appearance: -moz-window-button-minimize;
|
||||
}
|
||||
|
||||
#titlebar-max {
|
||||
-moz-appearance: -moz-window-button-maximize;
|
||||
}
|
||||
|
||||
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox > #titlebar-max {
|
||||
-moz-appearance: -moz-window-button-restore;
|
||||
}
|
||||
|
||||
#titlebar-close {
|
||||
-moz-appearance: -moz-window-button-close;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-classic) {
|
||||
#titlebar-min {
|
||||
-moz-margin-end: 1px;
|
||||
#navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] {
|
||||
position: relative !important;
|
||||
background-color: -moz-dialog !important;
|
||||
}
|
||||
|
||||
#titlebar-max {
|
||||
-moz-margin-start: 1px;
|
||||
-moz-margin-end: 1px;
|
||||
}
|
||||
|
||||
#titlebar-close {
|
||||
-moz-margin-start: 1px;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (-moz-windows-classic) {
|
||||
#titlebar-close {
|
||||
-moz-margin-start: 2px !important;
|
||||
#navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] ~ #TabsToolbar:not([inFullscreen]) {
|
||||
-moz-padding-start: 10em !important;
|
||||
}
|
||||
%ifdef WINSTRIPE_AERO
|
||||
}
|
||||
%endif
|
||||
|
||||
/* ::::: bookmark buttons ::::: */
|
||||
|
||||
|
|
|
@ -1100,6 +1100,10 @@ nsHTMLParanoidFragmentSink::CloseContainer(const nsHTMLTag aTag)
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mIgnoreNextCloseHead && aTag == eHTMLTag_head) {
|
||||
mIgnoreNextCloseHead = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (mSkip) {
|
||||
mSkip = PR_FALSE;
|
||||
return rv;
|
||||
|
@ -1229,7 +1233,10 @@ nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode)
|
|||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mSkip) {
|
||||
// We need to explicitly skip adding leaf nodes in the paranoid sink,
|
||||
// otherwise things like the textnode under <title> get appended to
|
||||
// the fragment itself, and won't be popped off in CloseContainer.
|
||||
if (mSkip || mIgnoreNextCloseHead) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "mozilla/plugins/BrowserStreamParent.h"
|
||||
#include "PluginIdentifierParent.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
|
@ -69,6 +70,7 @@ using mozilla::ipc::SyncChannel;
|
|||
using namespace mozilla::plugins;
|
||||
|
||||
static const char kTimeoutPref[] = "dom.ipc.plugins.timeoutSecs";
|
||||
static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs";
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::plugins::PluginModuleParent>
|
||||
|
@ -84,15 +86,21 @@ PluginModuleParent::LoadModule(const char* aFilePath)
|
|||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
|
||||
PRInt32 prefSecs = nsContentUtils::GetIntPref(kLaunchTimeoutPref, 0);
|
||||
|
||||
// Block on the child process being launched and initialized.
|
||||
PluginModuleParent* parent = new PluginModuleParent(aFilePath);
|
||||
parent->mSubprocess->Launch();
|
||||
nsAutoPtr<PluginModuleParent> parent(new PluginModuleParent(aFilePath));
|
||||
bool launched = parent->mSubprocess->Launch(prefSecs * 1000);
|
||||
if (!launched) {
|
||||
// Need to set this so the destructor doesn't complain.
|
||||
parent->mShutdown = true;
|
||||
return nsnull;
|
||||
}
|
||||
parent->Open(parent->mSubprocess->GetChannel(),
|
||||
parent->mSubprocess->GetChildProcessHandle());
|
||||
|
||||
TimeoutChanged(kTimeoutPref, parent);
|
||||
|
||||
return parent;
|
||||
return parent.forget();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,11 +68,11 @@ PluginProcessParent::~PluginProcessParent()
|
|||
}
|
||||
|
||||
bool
|
||||
PluginProcessParent::Launch()
|
||||
PluginProcessParent::Launch(PRInt32 timeoutMs)
|
||||
{
|
||||
vector<string> args;
|
||||
args.push_back(MungePluginDsoPath(mPluginFilePath));
|
||||
return SyncLaunch(args);
|
||||
return SyncLaunch(args, timeoutMs);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -61,9 +61,10 @@ public:
|
|||
~PluginProcessParent();
|
||||
|
||||
/**
|
||||
* Synchronously launch the plugin process.
|
||||
* Synchronously launch the plugin process. If the process fails to launch
|
||||
* after timeoutMs, this method will return false.
|
||||
*/
|
||||
bool Launch();
|
||||
bool Launch(PRInt32 timeoutMs);
|
||||
|
||||
void Delete();
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=520182
|
|||
<div id="jj" contenteditable="true"></div>
|
||||
<iframe id="kk" src="about:blank"></iframe>
|
||||
<div id="ll" contenteditable="true"></div>
|
||||
<iframe id="mm" src="about:blank"></iframe>
|
||||
<div id="nn" contenteditable="true"></div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
@ -73,6 +75,7 @@ const invalidStyle3Payload = "foo<style>@import 'xxx.css';</style>baz";
|
|||
const invalidStyle4Payload = "foo<span style=\"@import 'xxx.css';\">bar</span>baz";
|
||||
const invalidStyle5Payload = "foo<span style=\"@font-face{font-family:xxx;src:'xxx.ttf';}\">bar</span>baz";
|
||||
const invalidStyle6Payload = "foo<span style=\"@namespace xxx url(http://example.com/);\">bar</span>baz";
|
||||
const invalidStyle7Payload = "<html><head><title>xxx</title></head><body>foo</body></html>";
|
||||
const nestedStylePayload = "foo<style>#bar1{-moz-binding:url('data:text/xml,<?xml version="1.0"><binding xmlns="http://www.mozilla.org/xbl" id="binding-1"/>');<style></style>#bar2{-moz-binding:url('data:text/xml,<?xml version="1.0"><binding xmlns="http://www.mozilla.org/xbl" id="binding-2"/>');</style>baz";
|
||||
const validImgSrc1Payload = "foo<img src=\"data:image/png,bar\">baz";
|
||||
const validImgSrc2Payload = "foo<img src=\"javascript:void('bar');\">baz";
|
||||
|
@ -199,26 +202,26 @@ var tests = [
|
|||
{
|
||||
id: "s",
|
||||
isIFrame: true,
|
||||
payload: invalidStyle1Payload,
|
||||
payload: invalidStyle3Payload,
|
||||
rootElement: function() document.getElementById("s").contentDocument.documentElement,
|
||||
checkResult: function(html) is(html.indexOf("xxx"), -1, "Should not have retained the import style")
|
||||
},
|
||||
{
|
||||
id: "t",
|
||||
payload: invalidStyle1Payload,
|
||||
payload: invalidStyle3Payload,
|
||||
rootElement: function() document.getElementById("t"),
|
||||
checkResult: function(html) is(html.indexOf("xxx"), -1, "Should not have retained the import style")
|
||||
},
|
||||
{
|
||||
id: "u",
|
||||
isIFrame: true,
|
||||
payload: invalidStyle2Payload,
|
||||
payload: invalidStyle4Payload,
|
||||
rootElement: function() document.getElementById("u").contentDocument.documentElement,
|
||||
checkResult: function(html) is(html.indexOf("xxx"), -1, "Should not have retained the import style")
|
||||
},
|
||||
{
|
||||
id: "v",
|
||||
payload: invalidStyle2Payload,
|
||||
payload: invalidStyle4Payload,
|
||||
rootElement: function() document.getElementById("v"),
|
||||
checkResult: function(html) is(html.indexOf("xxx"), -1, "Should not have retained the import style")
|
||||
},
|
||||
|
@ -298,41 +301,62 @@ var tests = [
|
|||
{
|
||||
id: "gg",
|
||||
isIFrame: true,
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc1Payload,
|
||||
rootElement: function() document.getElementById("gg").contentDocument.documentElement,
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "hh",
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc1Payload,
|
||||
rootElement: function() document.getElementById("hh"),
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "ii",
|
||||
isIFrame: true,
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc2Payload,
|
||||
rootElement: function() document.getElementById("ii").contentDocument.documentElement,
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "jj",
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc2Payload,
|
||||
rootElement: function() document.getElementById("jj"),
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "kk",
|
||||
isIFrame: true,
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc3Payload,
|
||||
rootElement: function() document.getElementById("kk").contentDocument.documentElement,
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "ll",
|
||||
payload: invalidStyle6Payload,
|
||||
payload: validImgSrc3Payload,
|
||||
rootElement: function() document.getElementById("ll"),
|
||||
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
|
||||
},
|
||||
{
|
||||
id: "mm",
|
||||
isIFrame: true,
|
||||
insertHTML: true,
|
||||
payload: invalidStyle7Payload,
|
||||
rootElement: function() document.getElementById("mm").contentDocument.documentElement,
|
||||
checkResult: function(html) {
|
||||
is(html.indexOf("xxx"), -1, "Should not have retained the title text");
|
||||
isnot(html.indexOf("foo"), -1, "Should have retained the body text");
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "nn",
|
||||
insertHTML: true,
|
||||
payload: invalidStyle7Payload,
|
||||
rootElement: function() document.getElementById("nn"),
|
||||
checkResult: function(html) {
|
||||
is(html.indexOf("xxx"), -1, "Should not have retained the title text");
|
||||
isnot(html.indexOf("foo"), -1, "Should have retained the body text");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -357,28 +381,37 @@ function runTest(test) {
|
|||
} else
|
||||
elem.focus();
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
if ("insertHTML" in test) {
|
||||
if ("isIFrame" in test) {
|
||||
elem.contentDocument.execCommand("inserthtml", false, test.payload);
|
||||
} else {
|
||||
getSelection().collapse(elem, 0);
|
||||
document.execCommand("inserthtml", false, test.payload);
|
||||
}
|
||||
} else {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
var data = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
data.data = test.payload;
|
||||
trans.addDataFlavor("text/html");
|
||||
trans.setTransferData("text/html", data, data.data.length * 2);
|
||||
clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
var data = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
data.data = test.payload;
|
||||
trans.addDataFlavor("text/html");
|
||||
trans.setTransferData("text/html", data, data.data.length * 2);
|
||||
clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
|
||||
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
|
||||
mainWindow.goDoCommand("cmd_paste");
|
||||
mainWindow.goDoCommand("cmd_paste");
|
||||
}
|
||||
|
||||
if ("checkResult" in test) {
|
||||
if ("isIFrame" in test) {
|
||||
|
|
|
@ -107,7 +107,7 @@ static JSContext *autoconfig_cx = nsnull;
|
|||
static JSObject *autoconfig_glob;
|
||||
|
||||
static JSClass global_class = {
|
||||
"autoconfig_global", 0,
|
||||
"autoconfig_global", JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nsnull
|
||||
};
|
||||
|
|
|
@ -0,0 +1,546 @@
|
|||
#if 0
|
||||
//
|
||||
// FX Version: fx_4_0
|
||||
// Child effect (requires effect pool): false
|
||||
//
|
||||
// 1 local buffer(s)
|
||||
//
|
||||
cbuffer cb0
|
||||
{
|
||||
float4 QuadDesc; // Offset: 0, size: 16
|
||||
float4 TexCoords; // Offset: 16, size: 16
|
||||
}
|
||||
|
||||
//
|
||||
// 2 local object(s)
|
||||
//
|
||||
Texture2D tex;
|
||||
SamplerState sSampler
|
||||
{
|
||||
Texture = tex;
|
||||
AddressU = uint(CLAMP /* 3 */);
|
||||
AddressV = uint(CLAMP /* 3 */);
|
||||
};
|
||||
|
||||
//
|
||||
// 1 technique(s)
|
||||
//
|
||||
technique10 SampleTexture
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = asm {
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
//
|
||||
// Buffer Definitions:
|
||||
//
|
||||
// cbuffer cb0
|
||||
// {
|
||||
//
|
||||
// float4 QuadDesc; // Offset: 0 Size: 16
|
||||
// float4 TexCoords; // Offset: 16 Size: 16
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Resource Bindings:
|
||||
//
|
||||
// Name Type Format Dim Slot Elements
|
||||
// ------------------------------ ---------- ------- ----------- ---- --------
|
||||
// cb0 cbuffer NA NA 0 1
|
||||
//
|
||||
//
|
||||
//
|
||||
// Input signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------ ------
|
||||
// POSITION 0 xyz 0 NONE float xy
|
||||
//
|
||||
//
|
||||
// Output signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------ ------
|
||||
// SV_Position 0 xyzw 0 POS float xyzw
|
||||
// TEXCOORD 0 xy 1 NONE float xy
|
||||
//
|
||||
//
|
||||
// Constant buffer to DX9 shader constant mappings:
|
||||
//
|
||||
// Target Reg Buffer Start Reg # of Regs Data Conversion
|
||||
// ---------- ------- --------- --------- ----------------------
|
||||
// c1 cb0 0 2 ( FLT, FLT, FLT, FLT)
|
||||
//
|
||||
//
|
||||
// Runtime generated constant mappings:
|
||||
//
|
||||
// Target Reg Constant Description
|
||||
// ---------- --------------------------------------------------
|
||||
// c0 Vertex Shader position offset
|
||||
//
|
||||
//
|
||||
// Level9 shader bytecode:
|
||||
//
|
||||
vs_2_x
|
||||
def c3, 0, 1, 0, 0
|
||||
dcl_texcoord v0
|
||||
mad oT0.xy, v0, c2.zwzw, c2
|
||||
mad r0.x, v0.x, c1.z, c1.x
|
||||
mad r0.y, v0.y, c1.w, c1.y
|
||||
add oPos.xy, r0, c0
|
||||
mov oPos.zw, c3.xyxy
|
||||
|
||||
// approximately 5 instruction slots used
|
||||
vs_4_0
|
||||
dcl_constantbuffer cb0[2], immediateIndexed
|
||||
dcl_input v0.xy
|
||||
dcl_output_siv o0.xyzw, position
|
||||
dcl_output o1.xy
|
||||
mad o0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
|
||||
mov o0.zw, l(0,0,0,1.000000)
|
||||
mad o1.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
|
||||
ret
|
||||
// Approximately 4 instruction slots used
|
||||
|
||||
};
|
||||
GeometryShader = NULL;
|
||||
PixelShader = asm {
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
//
|
||||
// Resource Bindings:
|
||||
//
|
||||
// Name Type Format Dim Slot Elements
|
||||
// ------------------------------ ---------- ------- ----------- ---- --------
|
||||
// sSampler sampler NA NA 0 1
|
||||
// tex texture float4 2d 0 1
|
||||
//
|
||||
//
|
||||
//
|
||||
// Input signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------ ------
|
||||
// SV_Position 0 xyzw 0 POS float
|
||||
// TEXCOORD 0 xy 1 NONE float xy
|
||||
//
|
||||
//
|
||||
// Output signature:
|
||||
//
|
||||
// Name Index Mask Register SysValue Format Used
|
||||
// -------------------- ----- ------ -------- -------- ------ ------
|
||||
// SV_Target 0 xyzw 0 TARGET float xyzw
|
||||
//
|
||||
//
|
||||
// Sampler/Resource to DX9 shader sampler mappings:
|
||||
//
|
||||
// Target Sampler Source Sampler Source Resource
|
||||
// -------------- --------------- ----------------
|
||||
// s0 s0 t0
|
||||
//
|
||||
//
|
||||
// Level9 shader bytecode:
|
||||
//
|
||||
ps_2_x
|
||||
dcl t0.xy
|
||||
dcl_2d s0
|
||||
texld r0, t0, s0
|
||||
mov oC0, r0
|
||||
|
||||
// approximately 2 instruction slots used (1 texture, 1 arithmetic)
|
||||
ps_4_0
|
||||
dcl_sampler s0, mode_default
|
||||
dcl_resource_texture2d (float,float,float,float) t0
|
||||
dcl_input_ps linear v1.xy
|
||||
dcl_output o0.xyzw
|
||||
sample o0.xyzw, v1.xyxx, t0.xyzw, s0
|
||||
ret
|
||||
// Approximately 2 instruction slots used
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const BYTE g_main[] =
|
||||
{
|
||||
68, 88, 66, 67, 235, 24,
|
||||
238, 6, 37, 230, 191, 228,
|
||||
58, 61, 41, 219, 70, 130,
|
||||
61, 51, 1, 0, 0, 0,
|
||||
187, 8, 0, 0, 1, 0,
|
||||
0, 0, 36, 0, 0, 0,
|
||||
70, 88, 49, 48, 143, 8,
|
||||
0, 0, 1, 16, 255, 254,
|
||||
1, 0, 0, 0, 2, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 79, 7,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 2, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
0, 0, 0, 0, 99, 98,
|
||||
48, 0, 102, 108, 111, 97,
|
||||
116, 52, 0, 8, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 16, 0, 0,
|
||||
0, 16, 0, 0, 0, 16,
|
||||
0, 0, 0, 10, 33, 0,
|
||||
0, 81, 117, 97, 100, 68,
|
||||
101, 115, 99, 0, 84, 101,
|
||||
120, 67, 111, 111, 114, 100,
|
||||
115, 0, 84, 101, 120, 116,
|
||||
117, 114, 101, 50, 68, 0,
|
||||
62, 0, 0, 0, 2, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
12, 0, 0, 0, 116, 101,
|
||||
120, 0, 83, 97, 109, 112,
|
||||
108, 101, 114, 83, 116, 97,
|
||||
116, 101, 0, 104, 0, 0,
|
||||
0, 2, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 21, 0, 0,
|
||||
0, 115, 83, 97, 109, 112,
|
||||
108, 101, 114, 0, 1, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
3, 0, 0, 0, 1, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
3, 0, 0, 0, 83, 97,
|
||||
109, 112, 108, 101, 84, 101,
|
||||
120, 116, 117, 114, 101, 0,
|
||||
80, 48, 0, 172, 3, 0,
|
||||
0, 68, 88, 66, 67, 247,
|
||||
105, 31, 113, 120, 95, 58,
|
||||
12, 207, 141, 45, 76, 175,
|
||||
59, 223, 25, 1, 0, 0,
|
||||
0, 172, 3, 0, 0, 6,
|
||||
0, 0, 0, 56, 0, 0,
|
||||
0, 248, 0, 0, 0, 188,
|
||||
1, 0, 0, 56, 2, 0,
|
||||
0, 32, 3, 0, 0, 84,
|
||||
3, 0, 0, 65, 111, 110,
|
||||
57, 184, 0, 0, 0, 184,
|
||||
0, 0, 0, 0, 2, 254,
|
||||
255, 132, 0, 0, 0, 52,
|
||||
0, 0, 0, 1, 0, 36,
|
||||
0, 0, 0, 48, 0, 0,
|
||||
0, 48, 0, 0, 0, 36,
|
||||
0, 1, 0, 48, 0, 0,
|
||||
0, 0, 0, 2, 0, 1,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 2, 254,
|
||||
255, 81, 0, 0, 5, 3,
|
||||
0, 15, 160, 0, 0, 0,
|
||||
0, 0, 0, 128, 63, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 31, 0, 0, 2, 5,
|
||||
0, 0, 128, 0, 0, 15,
|
||||
144, 4, 0, 0, 4, 0,
|
||||
0, 3, 224, 0, 0, 228,
|
||||
144, 2, 0, 238, 160, 2,
|
||||
0, 228, 160, 4, 0, 0,
|
||||
4, 0, 0, 1, 128, 0,
|
||||
0, 0, 144, 1, 0, 170,
|
||||
160, 1, 0, 0, 160, 4,
|
||||
0, 0, 4, 0, 0, 2,
|
||||
128, 0, 0, 85, 144, 1,
|
||||
0, 255, 160, 1, 0, 85,
|
||||
160, 2, 0, 0, 3, 0,
|
||||
0, 3, 192, 0, 0, 228,
|
||||
128, 0, 0, 228, 160, 1,
|
||||
0, 0, 2, 0, 0, 12,
|
||||
192, 3, 0, 68, 160, 255,
|
||||
255, 0, 0, 83, 72, 68,
|
||||
82, 188, 0, 0, 0, 64,
|
||||
0, 1, 0, 47, 0, 0,
|
||||
0, 89, 0, 0, 4, 70,
|
||||
142, 32, 0, 0, 0, 0,
|
||||
0, 2, 0, 0, 0, 95,
|
||||
0, 0, 3, 50, 16, 16,
|
||||
0, 0, 0, 0, 0, 103,
|
||||
0, 0, 4, 242, 32, 16,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 101, 0, 0,
|
||||
3, 50, 32, 16, 0, 1,
|
||||
0, 0, 0, 50, 0, 0,
|
||||
11, 50, 32, 16, 0, 0,
|
||||
0, 0, 0, 70, 16, 16,
|
||||
0, 0, 0, 0, 0, 230,
|
||||
138, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 70,
|
||||
128, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 54,
|
||||
0, 0, 8, 194, 32, 16,
|
||||
0, 0, 0, 0, 0, 2,
|
||||
64, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 128,
|
||||
63, 50, 0, 0, 11, 50,
|
||||
32, 16, 0, 1, 0, 0,
|
||||
0, 70, 16, 16, 0, 0,
|
||||
0, 0, 0, 230, 138, 32,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 70, 128, 32,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 62, 0, 0,
|
||||
1, 83, 84, 65, 84, 116,
|
||||
0, 0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 82,
|
||||
68, 69, 70, 224, 0, 0,
|
||||
0, 1, 0, 0, 0, 64,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 28, 0, 0, 0, 0,
|
||||
4, 254, 255, 0, 129, 0,
|
||||
0, 174, 0, 0, 0, 60,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 99, 98, 48, 0, 60,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 88, 0, 0, 0, 32,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 136,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 16, 0, 0, 0, 2,
|
||||
0, 0, 0, 148, 0, 0,
|
||||
0, 0, 0, 0, 0, 164,
|
||||
0, 0, 0, 16, 0, 0,
|
||||
0, 16, 0, 0, 0, 2,
|
||||
0, 0, 0, 148, 0, 0,
|
||||
0, 0, 0, 0, 0, 81,
|
||||
117, 97, 100, 68, 101, 115,
|
||||
99, 0, 171, 171, 171, 1,
|
||||
0, 3, 0, 1, 0, 4,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 84, 101, 120,
|
||||
67, 111, 111, 114, 100, 115,
|
||||
0, 77, 105, 99, 114, 111,
|
||||
115, 111, 102, 116, 32, 40,
|
||||
82, 41, 32, 72, 76, 83,
|
||||
76, 32, 83, 104, 97, 100,
|
||||
101, 114, 32, 67, 111, 109,
|
||||
112, 105, 108, 101, 114, 32,
|
||||
57, 46, 50, 55, 46, 57,
|
||||
53, 50, 46, 51, 48, 50,
|
||||
50, 0, 171, 73, 83, 71,
|
||||
78, 44, 0, 0, 0, 1,
|
||||
0, 0, 0, 8, 0, 0,
|
||||
0, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 3, 0, 0, 0, 0,
|
||||
0, 0, 0, 7, 3, 0,
|
||||
0, 80, 79, 83, 73, 84,
|
||||
73, 79, 78, 0, 171, 171,
|
||||
171, 79, 83, 71, 78, 80,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 8, 0, 0, 0, 56,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 3,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 15, 0, 0, 0, 68,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 3,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 3, 12, 0, 0, 83,
|
||||
86, 95, 80, 111, 115, 105,
|
||||
116, 105, 111, 110, 0, 84,
|
||||
69, 88, 67, 79, 79, 82,
|
||||
68, 0, 171, 171, 171, 195,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 2,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 188, 2, 0, 0, 68,
|
||||
88, 66, 67, 90, 17, 243,
|
||||
62, 104, 14, 0, 40, 49,
|
||||
70, 150, 92, 77, 1, 115,
|
||||
141, 1, 0, 0, 0, 188,
|
||||
2, 0, 0, 6, 0, 0,
|
||||
0, 56, 0, 0, 0, 164,
|
||||
0, 0, 0, 16, 1, 0,
|
||||
0, 140, 1, 0, 0, 48,
|
||||
2, 0, 0, 136, 2, 0,
|
||||
0, 65, 111, 110, 57, 100,
|
||||
0, 0, 0, 100, 0, 0,
|
||||
0, 0, 2, 255, 255, 60,
|
||||
0, 0, 0, 40, 0, 0,
|
||||
0, 0, 0, 40, 0, 0,
|
||||
0, 40, 0, 0, 0, 40,
|
||||
0, 1, 0, 36, 0, 0,
|
||||
0, 40, 0, 0, 0, 0,
|
||||
0, 1, 2, 255, 255, 31,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
128, 0, 0, 3, 176, 31,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
144, 0, 8, 15, 160, 66,
|
||||
0, 0, 3, 0, 0, 15,
|
||||
128, 0, 0, 228, 176, 0,
|
||||
8, 228, 160, 1, 0, 0,
|
||||
2, 0, 8, 15, 128, 0,
|
||||
0, 228, 128, 255, 255, 0,
|
||||
0, 83, 72, 68, 82, 100,
|
||||
0, 0, 0, 64, 0, 0,
|
||||
0, 25, 0, 0, 0, 90,
|
||||
0, 0, 3, 0, 96, 16,
|
||||
0, 0, 0, 0, 0, 88,
|
||||
24, 0, 4, 0, 112, 16,
|
||||
0, 0, 0, 0, 0, 85,
|
||||
85, 0, 0, 98, 16, 0,
|
||||
3, 50, 16, 16, 0, 1,
|
||||
0, 0, 0, 101, 0, 0,
|
||||
3, 242, 32, 16, 0, 0,
|
||||
0, 0, 0, 69, 0, 0,
|
||||
9, 242, 32, 16, 0, 0,
|
||||
0, 0, 0, 70, 16, 16,
|
||||
0, 1, 0, 0, 0, 70,
|
||||
126, 16, 0, 0, 0, 0,
|
||||
0, 0, 96, 16, 0, 0,
|
||||
0, 0, 0, 62, 0, 0,
|
||||
1, 83, 84, 65, 84, 116,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 82,
|
||||
68, 69, 70, 156, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 28, 0, 0, 0, 0,
|
||||
4, 255, 255, 0, 129, 0,
|
||||
0, 105, 0, 0, 0, 92,
|
||||
0, 0, 0, 3, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 101, 0, 0, 0, 2,
|
||||
0, 0, 0, 5, 0, 0,
|
||||
0, 4, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 12,
|
||||
0, 0, 0, 115, 83, 97,
|
||||
109, 112, 108, 101, 114, 0,
|
||||
116, 101, 120, 0, 77, 105,
|
||||
99, 114, 111, 115, 111, 102,
|
||||
116, 32, 40, 82, 41, 32,
|
||||
72, 76, 83, 76, 32, 83,
|
||||
104, 97, 100, 101, 114, 32,
|
||||
67, 111, 109, 112, 105, 108,
|
||||
101, 114, 32, 57, 46, 50,
|
||||
55, 46, 57, 53, 50, 46,
|
||||
51, 48, 50, 50, 0, 171,
|
||||
171, 73, 83, 71, 78, 80,
|
||||
0, 0, 0, 2, 0, 0,
|
||||
0, 8, 0, 0, 0, 56,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 3,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 15, 0, 0, 0, 68,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 3,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 3, 3, 0, 0, 83,
|
||||
86, 95, 80, 111, 115, 105,
|
||||
116, 105, 111, 110, 0, 84,
|
||||
69, 88, 67, 79, 79, 82,
|
||||
68, 0, 171, 171, 171, 79,
|
||||
83, 71, 78, 44, 0, 0,
|
||||
0, 1, 0, 0, 0, 8,
|
||||
0, 0, 0, 32, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 0, 0,
|
||||
0, 0, 0, 0, 0, 15,
|
||||
0, 0, 0, 83, 86, 95,
|
||||
84, 97, 114, 103, 101, 116,
|
||||
0, 171, 171, 135, 4, 0,
|
||||
0, 0, 0, 0, 0, 4,
|
||||
0, 0, 0, 32, 0, 0,
|
||||
0, 0, 0, 0, 0, 2,
|
||||
0, 0, 0, 255, 255, 255,
|
||||
255, 0, 0, 0, 0, 43,
|
||||
0, 0, 0, 15, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 52, 0, 0,
|
||||
0, 15, 0, 0, 0, 0,
|
||||
0, 0, 0, 16, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 100, 0, 0, 0, 72,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 145, 0, 0,
|
||||
0, 117, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 255,
|
||||
255, 3, 0, 0, 0, 55,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 2, 0, 0, 0, 100,
|
||||
0, 0, 0, 46, 0, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 154, 0, 0,
|
||||
0, 47, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 166, 0, 0, 0, 0,
|
||||
0, 0, 0, 178, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 192, 0, 0,
|
||||
0, 3, 0, 0, 0, 0,
|
||||
0, 0, 0, 6, 0, 0,
|
||||
0, 0, 0, 0, 0, 7,
|
||||
0, 0, 0, 115, 4, 0,
|
||||
0, 8, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 123, 4, 0, 0, 7,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 7, 0, 0, 0, 71,
|
||||
7, 0, 0
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
// We store vertex coordinates and the quad shape in a constant buffer, this is
|
||||
// easy to update and allows us to use a single call to set the x, y, w, h of
|
||||
// the quad.
|
||||
// The QuadDesc and TexCoords both work as follows:
|
||||
// The x component is the quad left point, the y component is the top point
|
||||
// the z component is the width, and the w component is the height. The quad
|
||||
// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
|
||||
// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
|
||||
// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
|
||||
// space <0, 1.0f> left to right and top to bottom. The input vertices of the
|
||||
// shader stage always form a rectangle from {0, 0} - {1, 1}
|
||||
cbuffer cb0
|
||||
{
|
||||
float4 QuadDesc;
|
||||
float4 TexCoords;
|
||||
}
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
Texture2D tex;
|
||||
|
||||
sampler sSampler = sampler_state {
|
||||
Texture = tex;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
Output.Position.w = 1.0f;
|
||||
Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
|
||||
Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
|
||||
Output.Position.z = 0;
|
||||
Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
|
||||
Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
|
||||
return Output;
|
||||
}
|
||||
|
||||
float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
|
||||
{
|
||||
return tex.Sample(sSampler, In.TexCoord);
|
||||
};
|
||||
|
||||
technique10 SampleTexture
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
|
||||
}
|
||||
}
|
|
@ -49,10 +49,28 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "cairo-win32-refptr.h"
|
||||
#include "cairo-d2d-private-fx.h"
|
||||
#include "cairo-win32.h"
|
||||
|
||||
/* describes the type of the currently applied clip so that we can pop it */
|
||||
struct d2d_clip;
|
||||
|
||||
#define MAX_OPERATORS CAIRO_OPERATOR_HSL_LUMINOSITY + 1
|
||||
|
||||
struct _cairo_d2d_device
|
||||
{
|
||||
cairo_device_t base;
|
||||
|
||||
HMODULE mD3D10_1;
|
||||
RefPtr<ID3D10Device1> mD3D10Device;
|
||||
RefPtr<ID3D10Effect> mSampleEffect;
|
||||
RefPtr<ID3D10InputLayout> mInputLayout;
|
||||
RefPtr<ID3D10Buffer> mQuadBuffer;
|
||||
RefPtr<ID3D10RasterizerState> mRasterizerState;
|
||||
RefPtr<ID3D10BlendState> mBlendStates[MAX_OPERATORS];
|
||||
};
|
||||
typedef struct _cairo_d2d_device cairo_d2d_device_t;
|
||||
|
||||
struct _cairo_d2d_surface {
|
||||
_cairo_d2d_surface() : d2d_clip(NULL), clipping(false), isDrawing(false),
|
||||
textRenderingInit(true)
|
||||
|
@ -61,6 +79,10 @@ struct _cairo_d2d_surface {
|
|||
}
|
||||
|
||||
cairo_surface_t base;
|
||||
/* Device used by this surface
|
||||
* NOTE: In upstream cairo this is in the surface base class */
|
||||
cairo_d2d_device_t *device;
|
||||
|
||||
/** Render target of the texture we render to */
|
||||
RefPtr<ID2D1RenderTarget> rt;
|
||||
/** Surface containing our backstore */
|
||||
|
@ -103,6 +125,10 @@ struct _cairo_d2d_surface {
|
|||
/** Indicates if text rendering is initialized */
|
||||
bool textRenderingInit;
|
||||
|
||||
RefPtr<ID3D10RenderTargetView> buffer_rt_view;
|
||||
RefPtr<ID3D10ShaderResourceView> buffer_sr_view;
|
||||
|
||||
|
||||
//cairo_surface_clipper_t clipper;
|
||||
};
|
||||
typedef struct _cairo_d2d_surface cairo_d2d_surface_t;
|
||||
|
@ -124,104 +150,14 @@ typedef HRESULT (WINAPI*D3D10CreateDevice1Func)(
|
|||
ID3D10Device1 **ppDevice
|
||||
);
|
||||
|
||||
class D2DSurfFactory
|
||||
{
|
||||
public:
|
||||
static ID2D1Factory *Instance()
|
||||
{
|
||||
if (!mFactoryInstance) {
|
||||
D2D1CreateFactoryFunc createD2DFactory = (D2D1CreateFactoryFunc)
|
||||
GetProcAddress(LoadLibraryW(L"d2d1.dll"), "D2D1CreateFactory");
|
||||
if (createD2DFactory) {
|
||||
D2D1_FACTORY_OPTIONS options;
|
||||
#ifdef DEBUG
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#else
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
|
||||
#endif
|
||||
createD2DFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory),
|
||||
&options,
|
||||
(void**)&mFactoryInstance);
|
||||
}
|
||||
}
|
||||
return mFactoryInstance;
|
||||
}
|
||||
private:
|
||||
static ID2D1Factory *mFactoryInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* On usage of D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS:
|
||||
* documentation on D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
|
||||
* can be misleading. In fact, that flag gives no such indication. I pointed this
|
||||
* out to Bas in my email. However, Microsoft is in fact using this flag to
|
||||
* indicate "light weight" DX applications. By light weight they are essentially
|
||||
* referring to applications that are not games. The idea is that when you create
|
||||
* a DX game, the driver assumes that you will pretty much have a single instance
|
||||
* and therefore it doesn't try to hold back when it comes to GPU resource
|
||||
* allocation as long as it can crank out performance. In other words, the
|
||||
* priority in regular DX applications is to make that one application run as fast
|
||||
* as you can. For "light weight" applications, including D2D applications, the
|
||||
* priorities are a bit different. Now you are no longer going to have a single
|
||||
* (or very few) instances. You can have a lot of them (say, for example, a
|
||||
* separate DX context/device per browser tab). In such cases, the GPU resource
|
||||
* allocation scheme changes.
|
||||
*/
|
||||
class D3D10Factory
|
||||
{
|
||||
public:
|
||||
static ID3D10Device1 *Device()
|
||||
{
|
||||
if (!mDeviceInstance) {
|
||||
D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
|
||||
GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateDevice1");
|
||||
if (createD3DDevice) {
|
||||
HRESULT hr = createD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
D3D10_FEATURE_LEVEL_10_1,
|
||||
D3D10_1_SDK_VERSION,
|
||||
&mDeviceInstance);
|
||||
if (FAILED(hr)) {
|
||||
HRESULT hr = createD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
D3D10_FEATURE_LEVEL_10_0,
|
||||
D3D10_1_SDK_VERSION,
|
||||
&mDeviceInstance);
|
||||
if (FAILED(hr)) {
|
||||
/* TODO: D3D10Level9 might be slower than GDI */
|
||||
HRESULT hr = createD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
D3D10_FEATURE_LEVEL_9_3,
|
||||
D3D10_1_SDK_VERSION,
|
||||
&mDeviceInstance);
|
||||
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
mDeviceInstance->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mDeviceInstance;
|
||||
}
|
||||
private:
|
||||
static ID3D10Device1 *mDeviceInstance;
|
||||
};
|
||||
|
||||
typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)(
|
||||
void *pData,
|
||||
SIZE_T DataLength,
|
||||
UINT FXFlags,
|
||||
ID3D10Device *pDevice,
|
||||
ID3D10EffectPool *pEffectPool,
|
||||
ID3D10Effect **ppEffect
|
||||
);
|
||||
|
||||
RefPtr<ID2D1Brush>
|
||||
_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
||||
|
@ -229,8 +165,15 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
|||
bool unique = false);
|
||||
void
|
||||
_cairo_d2d_begin_draw_state(cairo_d2d_surface_t *d2dsurf);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_d2d_set_clip(cairo_d2d_surface_t *d2dsurf, cairo_clip_t *clip);
|
||||
|
||||
cairo_int_status_t _cairo_d2d_blend_temp_surface(cairo_d2d_surface_t *surf, cairo_operator_t op, ID2D1RenderTarget *rt, cairo_clip_t *clip, const cairo_rectangle_int_t *bounds = NULL);
|
||||
|
||||
RefPtr<ID2D1RenderTarget> _cairo_d2d_get_temp_rt(cairo_d2d_surface_t *surf, cairo_clip_t *clip);
|
||||
|
||||
cairo_operator_t _cairo_d2d_simplify_operator(cairo_operator_t op, const cairo_pattern_t *source);
|
||||
|
||||
#endif /* CAIRO_HAS_D2D_SURFACE */
|
||||
#endif /* CAIRO_D2D_PRIVATE_H */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1262,32 +1262,52 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
|||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_DWRITE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
op = _cairo_d2d_simplify_operator(op, source);
|
||||
|
||||
/* We can only handle operator SOURCE or OVER with the destination
|
||||
* having no alpha */
|
||||
if (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
/* We cannot handle operator SOURCE or CLEAR */
|
||||
if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_cairo_d2d_begin_draw_state (dst);
|
||||
_cairo_d2d_set_clip (dst, clip);
|
||||
RefPtr<ID2D1RenderTarget> target_rt = dst->rt;
|
||||
cairo_rectangle_int_t fontArea;
|
||||
#ifndef ALWAYS_MANUAL_COMPOSITE
|
||||
if (op != CAIRO_OPERATOR_OVER) {
|
||||
#endif
|
||||
target_rt = _cairo_d2d_get_temp_rt(dst, clip);
|
||||
|
||||
if (!target_rt) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
#ifndef ALWAYS_MANUAL_COMPOSITE
|
||||
} else {
|
||||
_cairo_d2d_begin_draw_state(dst);
|
||||
status = (cairo_int_status_t)_cairo_d2d_set_clip (dst, clip);
|
||||
|
||||
if (unlikely(status))
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE cleartype = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
D2D1_TEXT_ANTIALIAS_MODE highest_quality = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
|
||||
if (dst->base.content != CAIRO_CONTENT_COLOR) {
|
||||
cleartype = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
// If we're rendering to a temporary surface we cannot do sub-pixel AA.
|
||||
if (dst->base.content != CAIRO_CONTENT_COLOR || dst->rt.get() != target_rt.get()) {
|
||||
highest_quality = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
}
|
||||
|
||||
switch (scaled_font->options.antialias) {
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
dst->rt->SetTextAntialiasMode(cleartype);
|
||||
target_rt->SetTextAntialiasMode(highest_quality);
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
dst->rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
|
||||
target_rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
dst->rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
|
||||
target_rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
dst->rt->SetTextAntialiasMode(cleartype);
|
||||
target_rt->SetTextAntialiasMode(highest_quality);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1349,7 +1369,29 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
|||
D2D1::Matrix3x2F mat = _cairo_d2d_matrix_from_matrix(&dwritesf->mat);
|
||||
|
||||
if (transform) {
|
||||
dst->rt->SetTransform(mat);
|
||||
target_rt->SetTransform(mat);
|
||||
}
|
||||
|
||||
if (dst->rt.get() != target_rt.get()) {
|
||||
RefPtr<IDWriteGlyphRunAnalysis> analysis;
|
||||
DWRITE_MATRIX dwmat = _cairo_dwrite_matrix_from_matrix(&dwritesf->mat);
|
||||
DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
|
||||
1.0f,
|
||||
transform ? &dwmat : 0,
|
||||
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
|
||||
DWRITE_MEASURING_MODE_NATURAL,
|
||||
0,
|
||||
0,
|
||||
&analysis);
|
||||
|
||||
RECT bounds;
|
||||
analysis->GetAlphaTextureBounds(scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE ?
|
||||
DWRITE_TEXTURE_ALIASED_1x1 : DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
&bounds);
|
||||
fontArea.x = bounds.left;
|
||||
fontArea.y = bounds.top;
|
||||
fontArea.width = bounds.right - bounds.left;
|
||||
fontArea.height = bounds.bottom - bounds.top;
|
||||
}
|
||||
|
||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst,
|
||||
|
@ -1374,15 +1416,19 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
|||
brush->SetTransform(&mat_brush);
|
||||
}
|
||||
|
||||
dst->rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush);
|
||||
target_rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush);
|
||||
|
||||
if (transform) {
|
||||
dst->rt->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
target_rt->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
}
|
||||
|
||||
delete [] indices;
|
||||
delete [] offsets;
|
||||
delete [] advances;
|
||||
|
||||
if (target_rt.get() != dst->rt.get()) {
|
||||
return _cairo_d2d_blend_temp_surface(dst, op, target_rt, clip, &fontArea);
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,26 @@ _cairo_boxes_get_extents (const cairo_box_t *boxes,
|
|||
}
|
||||
}
|
||||
|
||||
/* This function will return 'true' if the containing_rectangle contains the
|
||||
* contained_rectangle, and false otherwise.
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_rectangle_contains (const cairo_rectangle_int_t *containing_rectangle,
|
||||
const cairo_rectangle_int_t *contained_rectangle)
|
||||
{
|
||||
if (containing_rectangle->x > contained_rectangle->x ||
|
||||
containing_rectangle->y > contained_rectangle->y)
|
||||
return FALSE;
|
||||
|
||||
if (containing_rectangle->x + containing_rectangle->width <
|
||||
contained_rectangle->x + contained_rectangle->width ||
|
||||
containing_rectangle->y + containing_rectangle->height <
|
||||
contained_rectangle->y + contained_rectangle->height)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* XXX We currently have a confusing mix of boxes and rectangles as
|
||||
* exemplified by this function. A #cairo_box_t is a rectangular area
|
||||
* represented by the coordinates of the upper left and lower right
|
||||
|
|
|
@ -107,6 +107,11 @@ public:
|
|||
return mPtr;
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return (mPtr ? true : false);
|
||||
|
|
|
@ -126,30 +126,88 @@ cairo_dwrite_font_face_create_for_dwrite_fontface(void *dwrite_font, void *dwrit
|
|||
#endif /* CAIRO_HAS_DWRITE_FONT */
|
||||
|
||||
#if CAIRO_HAS_D2D_SURFACE
|
||||
|
||||
struct _cairo_device
|
||||
{
|
||||
int type;
|
||||
int refcount;
|
||||
};
|
||||
typedef struct _cairo_device cairo_device_t;
|
||||
|
||||
/**
|
||||
* Create a D2D device
|
||||
*
|
||||
* \return New D2D device, NULL if creation failed.
|
||||
*/
|
||||
cairo_device_t *
|
||||
cairo_d2d_create_device();
|
||||
|
||||
/**
|
||||
* Releases a D2D device.
|
||||
*
|
||||
* \return References left to the device
|
||||
*/
|
||||
int
|
||||
cairo_release_device(cairo_device_t *device);
|
||||
|
||||
/**
|
||||
* Addrefs a D2D device.
|
||||
*
|
||||
* \return References to the device
|
||||
*/
|
||||
int
|
||||
cairo_addref_device(cairo_device_t *device);
|
||||
|
||||
/**
|
||||
* Flushes a D3D device. In most cases the surface backend will do this
|
||||
* internally, but when using a surfaces created from a shared handle this
|
||||
* should be executed manually when a different device is going to be accessing
|
||||
* the same surface data. This will also block until the device is finished
|
||||
* processing all work.
|
||||
*/
|
||||
void
|
||||
cairo_d2d_finish_device(cairo_device_t *device);
|
||||
|
||||
/**
|
||||
* Create a D2D surface for an HWND
|
||||
*
|
||||
* \param device Device used to create the surface
|
||||
* \param wnd Handle for the window
|
||||
* \param content Content of the window, should be COLOR_ALPHA for transparent windows
|
||||
* \return New cairo surface
|
||||
*/
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_d2d_surface_create_for_hwnd(HWND wnd, cairo_content_t content);
|
||||
cairo_d2d_surface_create_for_hwnd(cairo_device_t *device, HWND wnd, cairo_content_t content);
|
||||
|
||||
/**
|
||||
* Create a D2D surface of a certain size.
|
||||
*
|
||||
* \param device Device used to create the surface
|
||||
* \param format Cairo format of the surface
|
||||
* \param width Width of the surface
|
||||
* \param height Height of the surface
|
||||
* \return New cairo surface
|
||||
*/
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_d2d_surface_create(cairo_format_t format,
|
||||
cairo_d2d_surface_create(cairo_device_t *device,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/**
|
||||
* Create a D3D surface from a Texture SharedHandle, this is obtained from a
|
||||
* CreateTexture call on a D3D9 device. This has to be an A8R8G8B8 format
|
||||
* or an A8 format, the treatment of the alpha channel can be indicated using
|
||||
* the content parameter.
|
||||
*
|
||||
* \param device Device used to create the surface
|
||||
* \param handle Shared handle to the texture we want to wrap
|
||||
* \param content Content of the texture, COLOR_ALPHA for ARGB
|
||||
* \return New cairo surface
|
||||
*/
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo_content_t content);
|
||||
|
||||
/**
|
||||
* Present the backbuffer for a surface create for an HWND. This needs
|
||||
* to be called when the owner of the original window surface wants to
|
||||
|
@ -172,15 +230,6 @@ void cairo_d2d_present_backbuffer(cairo_surface_t *surface);
|
|||
*/
|
||||
void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip);
|
||||
|
||||
/**
|
||||
* Verify if D2D surfaces are actually supported. This will confirm the needed
|
||||
* hardware is available.
|
||||
*
|
||||
* \return True if the support is available. If false surface creation will
|
||||
* return error surfaces.
|
||||
*/
|
||||
cairo_bool_t cairo_d2d_has_support();
|
||||
|
||||
/**
|
||||
* Get a DC for the current render target. When selecting the retention option this
|
||||
* call can be relatively slow, since it may require reading back contents from the
|
||||
|
|
|
@ -271,6 +271,10 @@ cairo_private void
|
|||
_cairo_box_from_rectangle (cairo_box_t *box,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_rectangle_contains (const cairo_rectangle_int_t *containing_rectangle,
|
||||
const cairo_rectangle_int_t *contained_rectangle);
|
||||
|
||||
cairo_private void
|
||||
_cairo_box_round_to_rectangle (const cairo_box_t *box,
|
||||
cairo_rectangle_int_t *rectangle);
|
||||
|
|
|
@ -84,7 +84,10 @@ CPPSRCS = \
|
|||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
ifdef MOZ_ENABLE_D3D9_LAYER
|
||||
EXPORTS += LayerManagerD3D9.h
|
||||
EXPORTS += \
|
||||
LayerManagerD3D9.h \
|
||||
DeviceManagerD3D9.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS += \
|
||||
LayerManagerD3D9.cpp \
|
||||
|
@ -93,6 +96,7 @@ CPPSRCS += \
|
|||
ImageLayerD3D9.cpp \
|
||||
ColorLayerD3D9.cpp \
|
||||
CanvasLayerD3D9.cpp \
|
||||
DeviceManagerD3D9.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -70,9 +70,17 @@ CanvasLayerD3D9::Initialize(const Data& aData)
|
|||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, 0,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
if (mD3DManager->deviceManager()->HasDynamicTextures()) {
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, D3DUSAGE_DYNAMIC,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
} else {
|
||||
// D3DPOOL_MANAGED is fine here since we require Dynamic Textures for D3D9Ex
|
||||
// devices.
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, 0,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -230,7 +238,7 @@ CanvasLayerD3D9::RenderLayer()
|
|||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER);
|
||||
|
||||
if (!mGLBufferIsPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
|
|
|
@ -76,7 +76,7 @@ ColorLayerD3D9::RenderLayer()
|
|||
|
||||
device()->SetPixelShaderConstantF(0, color, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::SOLIDCOLORLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER);
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ ContainerLayerD3D9::RenderLayer()
|
|||
opacityVector[0] = opacity;
|
||||
device()->SetPixelShaderConstantF(0, opacityVector, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, renderTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
|
|
@ -0,0 +1,562 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "DeviceManagerD3D9.h"
|
||||
#include "LayerManagerD3D9Shaders.h"
|
||||
#include "ThebesLayerD3D9.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
const LPCWSTR kClassName = L"D3D9WindowClass";
|
||||
|
||||
#define USE_D3D9EX
|
||||
|
||||
typedef IDirect3D9* (WINAPI*Direct3DCreate9Func)(
|
||||
UINT SDKVersion
|
||||
);
|
||||
|
||||
typedef HRESULT (WINAPI*Direct3DCreate9ExFunc)(
|
||||
UINT SDKVersion,
|
||||
IDirect3D9Ex **ppD3D
|
||||
);
|
||||
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
SwapChainD3D9::SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager)
|
||||
: mDeviceManager(aDeviceManager)
|
||||
, mWnd(0)
|
||||
{
|
||||
mDeviceManager->mSwapChains.AppendElement(this);
|
||||
}
|
||||
|
||||
SwapChainD3D9::~SwapChainD3D9()
|
||||
{
|
||||
mDeviceManager->mSwapChains.RemoveElement(this);
|
||||
}
|
||||
|
||||
bool
|
||||
SwapChainD3D9::Init(HWND hWnd)
|
||||
{
|
||||
RECT r;
|
||||
::GetClientRect(hWnd, &r);
|
||||
|
||||
mWnd = hWnd;
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
pp.hDeviceWindow = mWnd;
|
||||
if (r.left == r.right || r.top == r.bottom) {
|
||||
pp.BackBufferHeight = 1;
|
||||
pp.BackBufferWidth = 1;
|
||||
}
|
||||
|
||||
HRESULT hr = mDeviceManager->device()->
|
||||
CreateAdditionalSwapChain(&pp,
|
||||
getter_AddRefs(mSwapChain));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to create swap chain for window.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SwapChainD3D9::PrepareForRendering()
|
||||
{
|
||||
RECT r;
|
||||
if (!::GetClientRect(mWnd, &r)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDeviceManager->VerifyReadyForRendering()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mSwapChain) {
|
||||
Init(mWnd);
|
||||
}
|
||||
|
||||
if (mSwapChain) {
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuffer->GetDesc(&desc);
|
||||
|
||||
if (desc.Width == r.right - r.left && desc.Height == r.bottom - r.top) {
|
||||
mDeviceManager->device()->SetRenderTarget(0, backBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
mSwapChain = nsnull;
|
||||
|
||||
Init(mWnd);
|
||||
|
||||
if (!mSwapChain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSwapChain->GetBackBuffer(0,
|
||||
D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
mDeviceManager->device()->SetRenderTarget(0, backBuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Present(const nsIntRect &aRect)
|
||||
{
|
||||
RECT r;
|
||||
r.left = aRect.x;
|
||||
r.top = aRect.y;
|
||||
r.right = aRect.XMost();
|
||||
r.bottom = aRect.YMost();
|
||||
|
||||
mSwapChain->Present(&r, &r, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainD3D9::Reset()
|
||||
{
|
||||
mSwapChain = nsnull;
|
||||
}
|
||||
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
DeviceManagerD3D9::DeviceManagerD3D9()
|
||||
: mHasDynamicTextures(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceManagerD3D9::Init()
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
HRESULT hr;
|
||||
|
||||
if (!GetClassInfoW(GetModuleHandle(NULL), kClassName, &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = GetModuleHandle(NULL);
|
||||
wc.lpfnWndProc = ::DefWindowProc;
|
||||
wc.lpszClassName = kClassName;
|
||||
if (!RegisterClassW(&wc)) {
|
||||
NS_WARNING("Failed to register window class for DeviceManager.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mFocusWnd = CreateWindow(kClassName, L"D3D9Window", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
|
||||
NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
if (!mFocusWnd) {
|
||||
NS_WARNING("Failed to create DeviceManagerD3D9 Window.");
|
||||
return false;
|
||||
}
|
||||
|
||||
HMODULE d3d9 = LoadLibraryW(L"d3d9.dll");
|
||||
Direct3DCreate9Func d3d9Create = (Direct3DCreate9Func)
|
||||
GetProcAddress(d3d9, "Direct3DCreate9");
|
||||
Direct3DCreate9ExFunc d3d9CreateEx = (Direct3DCreate9ExFunc)
|
||||
GetProcAddress(d3d9, "Direct3DCreate9Ex");
|
||||
|
||||
#ifdef USE_D3D9EX
|
||||
if (d3d9CreateEx) {
|
||||
hr = d3d9CreateEx(D3D_SDK_VERSION, getter_AddRefs(mD3D9Ex));
|
||||
if (SUCCEEDED(hr)) {
|
||||
mD3D9 = mD3D9Ex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mD3D9) {
|
||||
if (!d3d9Create) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mD3D9 = dont_AddRef(d3d9Create(D3D_SDK_VERSION));
|
||||
|
||||
if (!mD3D9) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferWidth = 1;
|
||||
pp.BackBufferHeight = 1;
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = mFocusWnd;
|
||||
|
||||
if (mD3D9Ex) {
|
||||
hr = mD3D9Ex->CreateDeviceEx(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mFocusWnd,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
NULL,
|
||||
getter_AddRefs(mDeviceEx));
|
||||
if (SUCCEEDED(hr)) {
|
||||
mDevice = mDeviceEx;
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
if (mDeviceEx->GetDeviceCaps(&caps)) {
|
||||
if (LACKS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
|
||||
// XXX - Should we actually hit this we'll need a CanvasLayer that
|
||||
// supports static D3DPOOL_DEFAULT textures.
|
||||
NS_WARNING("D3D9Ex device not used because of lack of support for \
|
||||
dynamic textures. This is unexpected.");
|
||||
mDevice = nsnull;
|
||||
mDeviceEx = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDevice) {
|
||||
hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mFocusWnd,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
getter_AddRefs(mDevice));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to create Device for DeviceManagerD3D9.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!VerifyCaps()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
|
||||
getter_AddRefs(mLayerVS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
|
||||
getter_AddRefs(mRGBPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPS,
|
||||
getter_AddRefs(mYCbCrPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPS,
|
||||
getter_AddRefs(mSolidColorPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
0,
|
||||
D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mVB),
|
||||
NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vertex *vertices;
|
||||
hr = mVB->Lock(0, 0, (void**)&vertices, 0);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vertices[0].x = vertices[0].y = 0;
|
||||
vertices[1].x = 1; vertices[1].y = 0;
|
||||
vertices[2].x = 0; vertices[2].y = 1;
|
||||
vertices[3].x = 1; vertices[3].y = 1;
|
||||
|
||||
mVB->Unlock();
|
||||
|
||||
hr = mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DVERTEXELEMENT9 elements[] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
|
||||
D3DDECLUSAGE_POSITION, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
mDevice->CreateVertexDeclaration(elements, getter_AddRefs(mVD));
|
||||
|
||||
nsCOMPtr<nsIConsoleService>
|
||||
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
|
||||
|
||||
if (console) {
|
||||
nsString msg;
|
||||
msg +=
|
||||
NS_LITERAL_STRING("Direct3D 9 DeviceManager Initialized Succesfully.\nDriver: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Driver));
|
||||
msg += NS_LITERAL_STRING("\nDescription: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Description));
|
||||
msg += NS_LITERAL_STRING("\nVersion: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsPrintfCString("%d.%d.%d.%d",
|
||||
HIWORD(identifier.DriverVersion.HighPart),
|
||||
LOWORD(identifier.DriverVersion.HighPart),
|
||||
HIWORD(identifier.DriverVersion.LowPart),
|
||||
LOWORD(identifier.DriverVersion.LowPart)));
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetupRenderState()
|
||||
{
|
||||
mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
mDevice->SetVertexDeclaration(mVD);
|
||||
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
already_AddRefed<SwapChainD3D9>
|
||||
DeviceManagerD3D9::CreateSwapChain(HWND hWnd)
|
||||
{
|
||||
nsRefPtr<SwapChainD3D9> swapChain = new SwapChainD3D9(this);
|
||||
|
||||
if (!swapChain->Init(hWnd)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return swapChain.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DeviceManagerD3D9::SetShaderMode(ShaderMode aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mRGBPS);
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mYCbCrPS);
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceManagerD3D9::VerifyReadyForRendering()
|
||||
{
|
||||
HRESULT hr = mDevice->TestCooperativeLevel();
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (IsD3D9Ex()) {
|
||||
hr = mDeviceEx->CheckDeviceState(mFocusWnd);
|
||||
if (FAILED(hr)) {
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferWidth = 1;
|
||||
pp.BackBufferHeight = 1;
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = mFocusWnd;
|
||||
|
||||
hr = mDeviceEx->ResetEx(&pp, NULL);
|
||||
// Handle D3DERR_DEVICEREMOVED!
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hr != D3DERR_DEVICENOTRESET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < mThebesLayers.Length(); i++) {
|
||||
mThebesLayers[i]->CleanResources();
|
||||
}
|
||||
for(unsigned int i = 0; i < mSwapChains.Length(); i++) {
|
||||
mSwapChains[i]->Reset();
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferWidth = 1;
|
||||
pp.BackBufferHeight = 1;
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = mFocusWnd;
|
||||
|
||||
hr = mDevice->Reset(&pp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceManagerD3D9::VerifyCaps()
|
||||
{
|
||||
D3DCAPS9 caps;
|
||||
HRESULT hr = mDevice->GetDeviceCaps(&caps);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.DevCaps, D3DDEVCAPS_TEXTUREVIDEOMEMORY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.SrcBlendCaps, D3DPBLENDCAPS_ONE) ||
|
||||
LACKS_CAP(caps.SrcBlendCaps, D3DBLEND_SRCALPHA) ||
|
||||
LACKS_CAP(caps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_ALPHA) ||
|
||||
HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_SQUAREONLY) ||
|
||||
(HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_POW2) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR) ||
|
||||
LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (caps.MaxTextureHeight < 4096 ||
|
||||
caps.MaxTextureWidth < 4096) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((caps.PixelShaderVersion & 0xffff) < 0x200 ||
|
||||
(caps.VertexShaderVersion & 0xffff) < 0x200) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HAS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
|
||||
mHasDynamicTextures = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
|
@ -0,0 +1,207 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_DEVICEMANAGERD3D9_H
|
||||
#define GFX_DEVICEMANAGERD3D9_H
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "d3d9.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class DeviceManagerD3D9;
|
||||
class ThebesLayerD3D9;
|
||||
|
||||
/**
|
||||
* SwapChain class, this class manages the swap chain belonging to a
|
||||
* LayerManagerD3D9.
|
||||
*/
|
||||
class THEBES_API SwapChainD3D9
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(SwapChainD3D9)
|
||||
public:
|
||||
~SwapChainD3D9();
|
||||
|
||||
/**
|
||||
* This function will prepare the device this swap chain belongs to for
|
||||
* rendering to this swap chain. Only after calling this function can the
|
||||
* swap chain be drawn to, and only until this function is called on another
|
||||
* swap chain belonging to this device will the device draw to it. Passed in
|
||||
* is the size of the swap chain. If the window size differs from the size
|
||||
* during the last call to this function the swap chain will resize. Note that
|
||||
* in no case does this function guarantee the backbuffer to still have its
|
||||
* old content.
|
||||
*/
|
||||
bool PrepareForRendering();
|
||||
|
||||
/**
|
||||
* This function will present the selected rectangle of the swap chain to
|
||||
* its associated window.
|
||||
*/
|
||||
void Present(const nsIntRect &aRect);
|
||||
|
||||
private:
|
||||
friend class DeviceManagerD3D9;
|
||||
|
||||
SwapChainD3D9(DeviceManagerD3D9 *aDeviceManager);
|
||||
|
||||
bool Init(HWND hWnd);
|
||||
|
||||
/**
|
||||
* This causes us to release our swap chain, clearing out our resource usage
|
||||
* so the master device may reset.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
nsRefPtr<IDirect3DSwapChain9> mSwapChain;
|
||||
nsRefPtr<DeviceManagerD3D9> mDeviceManager;
|
||||
HWND mWnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* Device manager, this class is used by the layer managers to share the D3D9
|
||||
* device and create swap chains for the individual windows the layer managers
|
||||
* belong to.
|
||||
*/
|
||||
class THEBES_API DeviceManagerD3D9
|
||||
{
|
||||
public:
|
||||
DeviceManagerD3D9();
|
||||
|
||||
// We want the nsrefcnt return value. So we cannot use the inline refcnt macro
|
||||
NS_IMPL_ADDREF(DeviceManagerD3D9)
|
||||
NS_IMPL_RELEASE(DeviceManagerD3D9)
|
||||
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* Sets up the render state for the device for layer rendering.
|
||||
*/
|
||||
void SetupRenderState();
|
||||
|
||||
/**
|
||||
* Create a swap chain setup to work with the specified window.
|
||||
*/
|
||||
already_AddRefed<SwapChainD3D9> CreateSwapChain(HWND hWnd);
|
||||
|
||||
IDirect3DDevice9 *device() { return mDevice; }
|
||||
|
||||
bool IsD3D9Ex() { return mDeviceEx; }
|
||||
|
||||
bool HasDynamicTextures() { return mHasDynamicTextures; }
|
||||
|
||||
enum ShaderMode {
|
||||
RGBLAYER,
|
||||
YCBCRLAYER,
|
||||
SOLIDCOLORLAYER
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode);
|
||||
|
||||
/**
|
||||
* We keep a list of all thebes layers since we need their D3DPOOL_DEFAULT
|
||||
* surfaces to be released when we want to reset the device.
|
||||
*/
|
||||
nsTArray<ThebesLayerD3D9*> mThebesLayers;
|
||||
private:
|
||||
friend class SwapChainD3D9;
|
||||
|
||||
/**
|
||||
* This function verifies the device is ready for rendering, internally this
|
||||
* will test the cooperative level of the device and reset the device if
|
||||
* needed. If this returns false subsequent rendering calls may return errors.
|
||||
*/
|
||||
bool VerifyReadyForRendering();
|
||||
|
||||
/* Array used to store all swap chains for device resets */
|
||||
nsTArray<SwapChainD3D9*> mSwapChains;
|
||||
|
||||
/* The D3D device we use */
|
||||
nsRefPtr<IDirect3DDevice9> mDevice;
|
||||
|
||||
/* The D3D9Ex device - only valid on Vista+ with WDDM */
|
||||
nsRefPtr<IDirect3DDevice9Ex> mDeviceEx;
|
||||
|
||||
/* An instance of the D3D9 object */
|
||||
nsRefPtr<IDirect3D9> mD3D9;
|
||||
|
||||
/* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */
|
||||
nsRefPtr<IDirect3D9Ex> mD3D9Ex;
|
||||
|
||||
/* Vertex shader used for layer quads */
|
||||
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mRGBPS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mYCbCrPS;
|
||||
|
||||
/* Pixel shader used for solid colors */
|
||||
nsRefPtr<IDirect3DPixelShader9> mSolidColorPS;
|
||||
|
||||
/* Vertex buffer containing our basic vertex structure */
|
||||
nsRefPtr<IDirect3DVertexBuffer9> mVB;
|
||||
|
||||
/* Our vertex declaration */
|
||||
nsRefPtr<IDirect3DVertexDeclaration9> mVD;
|
||||
|
||||
/* Our focus window - this is really a dummy window we can associate our
|
||||
* device with.
|
||||
*/
|
||||
HWND mFocusWnd;
|
||||
|
||||
/* If this device supports dynamic textures */
|
||||
bool mHasDynamicTextures;
|
||||
|
||||
nsAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
/**
|
||||
* Verifies all required device capabilities are present.
|
||||
*/
|
||||
bool VerifyCaps();
|
||||
};
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* GFX_DEVICEMANAGERD3D9_H */
|
|
@ -185,7 +185,7 @@ ImageLayerD3D9::RenderLayer()
|
|||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::YCBCRLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER);
|
||||
|
||||
device()->SetTexture(0, yuvImage->mYTexture);
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
|
@ -227,7 +227,7 @@ ImageLayerD3D9::RenderLayer()
|
|||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, cairoImage->mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
@ -244,6 +244,7 @@ PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9(mozilla::layers::LayerManagerD3D9* aM
|
|||
void
|
||||
PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
// XXX - For D3D9Ex we really should just copy to systemmem surfaces here.
|
||||
// For now, we copy the data
|
||||
int width_shift = 0;
|
||||
int height_shift = 0;
|
||||
|
@ -309,76 +310,116 @@ PlanarYCbCrImageD3D9::AllocateTextures()
|
|||
{
|
||||
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
D3DLOCKED_RECT lockrectY;
|
||||
D3DLOCKED_RECT lockrectCb;
|
||||
D3DLOCKED_RECT lockrectCr;
|
||||
PRUint8* src;
|
||||
PRUint8* dest;
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceY;
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceCb;
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceCr;
|
||||
|
||||
/* lock the entire texture */
|
||||
mYTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
// D3D9Ex does not support the managed pool, could use dynamic textures
|
||||
// here. But since an Image is immutable static textures are probably a
|
||||
// better idea.
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mYSize.width,
|
||||
mData.mYSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceY),
|
||||
NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mCbCrSize.width,
|
||||
mData.mCbCrSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceCb),
|
||||
NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mCbCrSize.width,
|
||||
mData.mCbCrSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceCr),
|
||||
NULL);
|
||||
tmpSurfaceY->LockRect(&lockrectY, NULL, 0);
|
||||
tmpSurfaceCb->LockRect(&lockrectCb, NULL, 0);
|
||||
tmpSurfaceCr->LockRect(&lockrectCr, NULL, 0);
|
||||
} else {
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
|
||||
/* lock the entire texture */
|
||||
mYTexture->LockRect(0, &lockrectY, NULL, 0);
|
||||
mCbTexture->LockRect(0, &lockrectCb, NULL, 0);
|
||||
mCrTexture->LockRect(0, &lockrectCr, NULL, 0);
|
||||
}
|
||||
|
||||
src = mData.mYChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
dest = (PRUint8*)lockrectY.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mYSize.height; h++) {
|
||||
memcpy(dest, src, mData.mYSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
dest += lockrectY.Pitch;
|
||||
src += mData.mYStride;
|
||||
}
|
||||
|
||||
mYTexture->UnlockRect(0);
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCbTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCbChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
dest = (PRUint8*)lockrectCb.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
dest += lockrectCb.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCbTexture->UnlockRect(0);
|
||||
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCrTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCrChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
dest = (PRUint8*)lockrectCr.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
dest += lockrectCr.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCrTexture->UnlockRect(0);
|
||||
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
tmpSurfaceY->UnlockRect();
|
||||
tmpSurfaceCb->UnlockRect();
|
||||
tmpSurfaceCr->UnlockRect();
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
mYTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceY, NULL, dstSurface, NULL);
|
||||
mCbTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceCb, NULL, dstSurface, NULL);
|
||||
mCrTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceCr, NULL, dstSurface, NULL);
|
||||
} else {
|
||||
mYTexture->UnlockRect(0);
|
||||
mCbTexture->UnlockRect(0);
|
||||
mCrTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -426,31 +467,49 @@ CairoImageD3D9::SetData(const CairoImage::Data &aData)
|
|||
context->SetSource(aData.mSurface);
|
||||
context->Paint();
|
||||
|
||||
//XXX: make sure we're using the correct usage flags
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
// D3D9Ex doesn't support managed textures. We could use dynamic textures
|
||||
// here but since Images are immutable that probably isn't such a great
|
||||
// idea.
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
nsRefPtr<IDirect3DSurface9> surface;
|
||||
mManager->device()->CreateOffscreenPlainSurface(aData.mSize.width,
|
||||
aData.mSize.height,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(surface),
|
||||
NULL);
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
surface->LockRect(&lockedRect, NULL, 0);
|
||||
for (int y = 0; y < aData.mSize.height; y++) {
|
||||
memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y,
|
||||
imageSurface->Data() + imageSurface->Stride() * y,
|
||||
aData.mSize.width * 4);
|
||||
}
|
||||
surface->UnlockRect();
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(surface, NULL, dstSurface, NULL);
|
||||
} else {
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
D3DLOCKED_RECT lockrect;
|
||||
/* lock the entire texture */
|
||||
mTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
/* lock the entire texture */
|
||||
mTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
// copy over data. If we don't need to do any swaping we can
|
||||
// use memcpy
|
||||
for (int y = 0; y < aData.mSize.height; y++) {
|
||||
memcpy((char*)lockrect.pBits + lockrect.Pitch * y,
|
||||
imageSurface->Data() + imageSurface->Stride() * y,
|
||||
aData.mSize.width * 4);
|
||||
}
|
||||
|
||||
PRUint8* src = imageSurface->Data();
|
||||
//FIX cast
|
||||
PRUint8* dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data. If we don't need to do any swaping we can
|
||||
// use memcpy
|
||||
for (int i=0; i<aData.mSize.width*aData.mSize.height; i++) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
|
|
|
@ -43,25 +43,10 @@
|
|||
#include "ColorLayerD3D9.h"
|
||||
#include "CanvasLayerD3D9.h"
|
||||
|
||||
#include "LayerManagerD3D9Shaders.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
IDirect3D9 *LayerManagerD3D9::mD3D9 = NULL;
|
||||
|
||||
typedef IDirect3D9* (WINAPI*Direct3DCreate9Func)(
|
||||
UINT SDKVersion
|
||||
);
|
||||
|
||||
DeviceManagerD3D9 *LayerManagerD3D9::mDeviceManager = nsnull;
|
||||
|
||||
LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
|
||||
{
|
||||
|
@ -72,145 +57,39 @@ LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
|
|||
|
||||
LayerManagerD3D9::~LayerManagerD3D9()
|
||||
{
|
||||
}
|
||||
/* Important to release this first since it also holds a reference to the
|
||||
* device manager
|
||||
*/
|
||||
mSwapChain = nsnull;
|
||||
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
if (mDeviceManager) {
|
||||
if (!mDeviceManager->Release()) {
|
||||
mDeviceManager = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::Initialize()
|
||||
{
|
||||
if (!mD3D9) {
|
||||
Direct3DCreate9Func d3d9create = (Direct3DCreate9Func)
|
||||
GetProcAddress(LoadLibraryW(L"d3d9.dll"), "Direct3DCreate9");
|
||||
if (!d3d9create) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (!mDeviceManager) {
|
||||
mDeviceManager = new DeviceManagerD3D9;
|
||||
|
||||
mD3D9 = d3d9create(D3D_SDK_VERSION);
|
||||
if (!mD3D9) {
|
||||
if (!mDeviceManager->Init()) {
|
||||
mDeviceManager = nsnull;
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
mDeviceManager->AddRef();
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
mSwapChain = mDeviceManager->
|
||||
CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
|
||||
HRESULT hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
NULL,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
getter_AddRefs(mDevice));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
if (!mSwapChain) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!VerifyCaps()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
|
||||
getter_AddRefs(mLayerVS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
|
||||
getter_AddRefs(mRGBPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPS,
|
||||
getter_AddRefs(mYCbCrPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPS,
|
||||
getter_AddRefs(mSolidColorPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
|
||||
0,
|
||||
0,
|
||||
D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mVB),
|
||||
NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertex *vertices;
|
||||
hr = mVB->Lock(0, 0, (void**)&vertices, 0);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertices[0].x = vertices[0].y = 0;
|
||||
vertices[1].x = 1; vertices[1].y = 0;
|
||||
vertices[2].x = 0; vertices[2].y = 1;
|
||||
vertices[3].x = 1; vertices[3].y = 1;
|
||||
|
||||
mVB->Unlock();
|
||||
|
||||
hr = mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
D3DVERTEXELEMENT9 elements[] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
|
||||
D3DDECLUSAGE_POSITION, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
mDevice->CreateVertexDeclaration(elements, getter_AddRefs(mVD));
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
nsCOMPtr<nsIConsoleService>
|
||||
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
|
||||
|
||||
if (console) {
|
||||
nsString msg;
|
||||
msg +=
|
||||
NS_LITERAL_STRING("Direct3D 9 LayerManager Initialized Succesfully.\nDriver: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Driver));
|
||||
msg += NS_LITERAL_STRING("\nDescription: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Description));
|
||||
msg += NS_LITERAL_STRING("\nVersion: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsPrintfCString("%d.%d.%d.%d",
|
||||
HIWORD(identifier.DriverVersion.HighPart),
|
||||
LOWORD(identifier.DriverVersion.HighPart),
|
||||
HIWORD(identifier.DriverVersion.LowPart),
|
||||
LOWORD(identifier.DriverVersion.LowPart)));
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -298,38 +177,21 @@ LayerManagerD3D9::CreateImageContainer()
|
|||
return container.forget();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetShaderMode(ShaderMode aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mRGBPS);
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mYCbCrPS);
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::Render()
|
||||
{
|
||||
if (!SetupBackBuffer()) {
|
||||
if (!mSwapChain->PrepareForRendering()) {
|
||||
return;
|
||||
}
|
||||
deviceManager()->SetupRenderState();
|
||||
|
||||
SetupPipeline();
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
mDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0, 0);
|
||||
device()->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 0, 0);
|
||||
|
||||
mDevice->BeginScene();
|
||||
device()->BeginScene();
|
||||
|
||||
if (mRootLayer) {
|
||||
const nsIntRect *clipRect = mRootLayer->GetLayer()->GetClipRect();
|
||||
|
@ -344,24 +206,18 @@ LayerManagerD3D9::Render()
|
|||
r.right = rect.width;
|
||||
r.bottom = rect.height;
|
||||
}
|
||||
mDevice->SetScissorRect(&r);
|
||||
device()->SetScissorRect(&r);
|
||||
|
||||
mRootLayer->RenderLayer();
|
||||
}
|
||||
|
||||
mDevice->EndScene();
|
||||
device()->EndScene();
|
||||
|
||||
if (!mTarget) {
|
||||
const nsIntRect *r;
|
||||
for (nsIntRegionRectIterator iter(mClippingRegion);
|
||||
(r = iter.Next()) != nsnull;) {
|
||||
RECT rect;
|
||||
rect.left = r->x;
|
||||
rect.top = r->y;
|
||||
rect.right = r->XMost();
|
||||
rect.bottom = r->YMost();
|
||||
|
||||
mDevice->Present(&rect, &rect, NULL, NULL);
|
||||
mSwapChain->Present(*r);
|
||||
}
|
||||
} else {
|
||||
PaintToTarget();
|
||||
|
@ -387,86 +243,29 @@ LayerManagerD3D9::SetupPipeline()
|
|||
viewMatrix[3][1] = 1.0f;
|
||||
viewMatrix[3][3] = 1.0f;
|
||||
|
||||
HRESULT hr = mDevice->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
HRESULT hr = device()->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to set projection shader constant!");
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::SetupBackBuffer()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
backBuffer->GetDesc(&desc);
|
||||
|
||||
HRESULT hr = mDevice->TestCooperativeLevel();
|
||||
|
||||
/* The device is lost or something else is wrong, failure */
|
||||
if (FAILED(hr) && hr != D3DERR_DEVICENOTRESET) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the backbuffer is the right size, and the device is not lost, we can
|
||||
* safely render without doing anything.
|
||||
*/
|
||||
if ((desc.Width == rect.width && desc.Height == rect.height) &&
|
||||
SUCCEEDED(hr)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our device is lost or our backbuffer needs resizing, start by clearing
|
||||
* out all D3DPOOL_DEFAULT surfaces.
|
||||
*/
|
||||
for(unsigned int i = 0; i < mThebesLayers.Length(); i++) {
|
||||
mThebesLayers[i]->CleanResources();
|
||||
}
|
||||
|
||||
backBuffer = NULL;
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
hr = mDevice->Reset(&pp);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::PaintToTarget()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuff;
|
||||
nsRefPtr<IDirect3DSurface9> destSurf;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
device()->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuff));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuff->GetDesc(&desc);
|
||||
|
||||
mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height,
|
||||
device()->CreateOffscreenPlainSurface(desc.Width, desc.Height,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(destSurf), NULL);
|
||||
|
||||
mDevice->GetRenderTargetData(backBuff, destSurf);
|
||||
device()->GetRenderTargetData(backBuff, destSurf);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY);
|
||||
|
@ -483,81 +282,6 @@ LayerManagerD3D9::PaintToTarget()
|
|||
destSurf->UnlockRect();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetupRenderState()
|
||||
{
|
||||
mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
mDevice->SetVertexDeclaration(mVD);
|
||||
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::VerifyCaps()
|
||||
{
|
||||
D3DCAPS9 caps;
|
||||
HRESULT hr = mDevice->GetDeviceCaps(&caps);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.DevCaps, D3DDEVCAPS_TEXTUREVIDEOMEMORY)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.SrcBlendCaps, D3DPBLENDCAPS_ONE) ||
|
||||
LACKS_CAP(caps.SrcBlendCaps, D3DBLEND_SRCALPHA) ||
|
||||
LACKS_CAP(caps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_ALPHA) ||
|
||||
HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_SQUAREONLY) ||
|
||||
(HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_POW2) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR) ||
|
||||
LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (caps.MaxTextureHeight < 4096 ||
|
||||
caps.MaxTextureWidth < 4096) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((caps.PixelShaderVersion & 0xffff) < 0x200 ||
|
||||
(caps.VertexShaderVersion & 0xffff) < 0x200) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
LayerD3D9::LayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: mD3DManager(aManager)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "gfxContext.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "DeviceManagerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -122,49 +124,27 @@ public:
|
|||
*/
|
||||
void SetClippingEnabled(PRBool aEnabled);
|
||||
|
||||
IDirect3DDevice9 *device() const { return mDevice; }
|
||||
void SetShaderMode(DeviceManagerD3D9::ShaderMode aMode)
|
||||
{ mDeviceManager->SetShaderMode(aMode); }
|
||||
|
||||
enum ShaderMode {
|
||||
RGBLAYER,
|
||||
YCBCRLAYER,
|
||||
SOLIDCOLORLAYER
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode);
|
||||
|
||||
nsTArray<ThebesLayerD3D9*> mThebesLayers;
|
||||
IDirect3DDevice9 *device() const { return mDeviceManager->device(); }
|
||||
DeviceManagerD3D9 *deviceManager() const { return mDeviceManager; }
|
||||
|
||||
private:
|
||||
/* Direct3D9 instance */
|
||||
static IDirect3D9 *mD3D9;
|
||||
/* Device manager instance */
|
||||
static DeviceManagerD3D9 *mDeviceManager;
|
||||
|
||||
/* Swap chain associated with this layer manager */
|
||||
nsRefPtr<SwapChainD3D9> mSwapChain;
|
||||
|
||||
/* Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
|
||||
/*
|
||||
* Context target, NULL when drawing directly to our swap chain.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsRefPtr<IDirect3DDevice9> mDevice;
|
||||
|
||||
/* Vertex shader used for layer quads */
|
||||
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mRGBPS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mYCbCrPS;
|
||||
|
||||
/* Pixel shader used for solid colors */
|
||||
nsRefPtr<IDirect3DPixelShader9> mSolidColorPS;
|
||||
|
||||
/* Vertex buffer containing our basic vertex structure */
|
||||
nsRefPtr<IDirect3DVertexBuffer9> mVB;
|
||||
|
||||
/* Our vertex declaration */
|
||||
nsRefPtr<IDirect3DVertexDeclaration9> mVD;
|
||||
|
||||
/* Current root layer. */
|
||||
LayerD3D9 *mRootLayer;
|
||||
|
||||
|
@ -175,32 +155,21 @@ private:
|
|||
* Region we're clipping our current drawing to.
|
||||
*/
|
||||
nsIntRegion mClippingRegion;
|
||||
|
||||
/*
|
||||
* Render the current layer tree to the active target.
|
||||
*/
|
||||
void Render();
|
||||
|
||||
/*
|
||||
* Setup the pipeline.
|
||||
*/
|
||||
void SetupPipeline();
|
||||
/*
|
||||
* Setup the backbuffer.
|
||||
*
|
||||
* \return PR_TRUE if setup was succesful
|
||||
*/
|
||||
PRBool SetupBackBuffer();
|
||||
/*
|
||||
* Setup the render state for the surface.
|
||||
*/
|
||||
void SetupRenderState();
|
||||
|
||||
/*
|
||||
* Copies the content of our backbuffer to the set transaction target.
|
||||
*/
|
||||
void PaintToTarget();
|
||||
/*
|
||||
* Verifies all required device capabilities are present.
|
||||
*/
|
||||
PRBool VerifyCaps();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "gfxPlatform.h"
|
||||
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
#include "gfxD2DSurface.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -69,12 +72,12 @@ ThebesLayerD3D9::ThebesLayerD3D9(LayerManagerD3D9 *aManager)
|
|||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
aManager->mThebesLayers.AppendElement(this);
|
||||
aManager->deviceManager()->mThebesLayers.AppendElement(this);
|
||||
}
|
||||
|
||||
ThebesLayerD3D9::~ThebesLayerD3D9()
|
||||
{
|
||||
mD3DManager->mThebesLayers.RemoveElement(this);
|
||||
mD3DManager->deviceManager()->mThebesLayers.RemoveElement(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,7 +104,8 @@ ThebesLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
|||
return;
|
||||
}
|
||||
|
||||
D3DFORMAT fmt = UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
|
||||
D3DFORMAT fmt = (UseOpaqueSurface(this) && !mD2DSurface) ?
|
||||
D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
mTexture->GetLevelDesc(0, &desc);
|
||||
|
@ -116,10 +120,8 @@ ThebesLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
|||
|
||||
nsIntRect oldBounds = oldVisibleRegion.GetBounds();
|
||||
nsIntRect newBounds = mVisibleRegion.GetBounds();
|
||||
|
||||
device()->CreateTexture(newBounds.width, newBounds.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, fmt,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
|
||||
CreateNewTexture(gfxIntSize(newBounds.width, newBounds.height));
|
||||
|
||||
// Old visible region will become the region that is covered by both the
|
||||
// old and the new visible region.
|
||||
|
@ -191,13 +193,14 @@ ThebesLayerD3D9::RenderLayer()
|
|||
if (mVisibleRegion.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
HRESULT hr;
|
||||
|
||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
||||
|
||||
// We differentiate between these formats since D3D9 will only allow us to
|
||||
// call GetDC on an opaque surface.
|
||||
D3DFORMAT fmt = UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
|
||||
D3DFORMAT fmt = (UseOpaqueSurface(this) && !mD2DSurface) ?
|
||||
D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
|
||||
|
||||
if (mTexture) {
|
||||
D3DSURFACE_DESC desc;
|
||||
mTexture->GetLevelDesc(0, &desc);
|
||||
|
@ -211,103 +214,16 @@ ThebesLayerD3D9::RenderLayer()
|
|||
}
|
||||
|
||||
if (!mTexture) {
|
||||
device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, fmt,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
CreateNewTexture(gfxIntSize(visibleRect.width, visibleRect.height));
|
||||
mValidRegion.SetEmpty();
|
||||
}
|
||||
|
||||
if (!mValidRegion.IsEqual(mVisibleRegion)) {
|
||||
nsIntRegion region;
|
||||
region.Sub(mVisibleRegion, mValidRegion);
|
||||
nsIntRect bounds = region.GetBounds();
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatARGB32;
|
||||
nsRefPtr<gfxASurface> destinationSurface;
|
||||
nsRefPtr<gfxContext> context;
|
||||
DrawRegion(region);
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> tmpTexture;
|
||||
device()->CreateTexture(bounds.width, bounds.height, 1,
|
||||
0, fmt,
|
||||
D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), NULL);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> surf;
|
||||
HDC dc;
|
||||
if (UseOpaqueSurface(this)) {
|
||||
hr = tmpTexture->GetSurfaceLevel(0, getter_AddRefs(surf));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
// Uh-oh, bail.
|
||||
NS_WARNING("Failed to get texture surface level.");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = surf->GetDC(&dc);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to get device context for texture surface.");
|
||||
return;
|
||||
}
|
||||
|
||||
destinationSurface = new gfxWindowsSurface(dc);
|
||||
} else {
|
||||
// XXX - We may consider retaining a SYSTEMMEM texture texture the size
|
||||
// of our DEFAULT texture and then use UpdateTexture and add dirty rects
|
||||
// to update in a single call.
|
||||
destinationSurface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(bounds.width,
|
||||
bounds.height),
|
||||
imageFormat);
|
||||
}
|
||||
|
||||
context = new gfxContext(destinationSurface);
|
||||
context->Translate(gfxPoint(-bounds.x, -bounds.y));
|
||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||
cbInfo.Callback(this, context, region, nsIntRegion(), cbInfo.CallbackData);
|
||||
|
||||
if (UseOpaqueSurface(this)) {
|
||||
surf->ReleaseDC(dc);
|
||||
} else {
|
||||
D3DLOCKED_RECT r;
|
||||
tmpTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface =
|
||||
new gfxImageSurface((unsigned char *)r.pBits,
|
||||
gfxIntSize(bounds.width,
|
||||
bounds.height),
|
||||
r.Pitch,
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(imgSurface);
|
||||
context->SetSource(destinationSurface);
|
||||
context->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
context->Paint();
|
||||
|
||||
imgSurface = NULL;
|
||||
|
||||
tmpTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> srcSurface;
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
tmpTexture->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
|
||||
|
||||
nsIntRegionRectIterator iter(region);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
RECT rect;
|
||||
rect.left = iterRect->x - bounds.x;
|
||||
rect.top = iterRect->y - bounds.y;
|
||||
rect.right = rect.left + iterRect->width;
|
||||
rect.bottom = rect.top + iterRect->height;
|
||||
POINT point;
|
||||
point.x = iterRect->x - visibleRect.x;
|
||||
point.y = iterRect->y - visibleRect.y;
|
||||
device()->UpdateSurface(srcSurface, &rect, dstSurface, &point);
|
||||
}
|
||||
mValidRegion = mVisibleRegion;
|
||||
}
|
||||
|
||||
|
@ -338,7 +254,7 @@ ThebesLayerD3D9::RenderLayer()
|
|||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
@ -362,5 +278,168 @@ ThebesLayerD3D9::IsEmpty()
|
|||
return !mTexture;
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::DrawRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
HRESULT hr;
|
||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
||||
nsRefPtr<gfxContext> context;
|
||||
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
if (mD2DSurface) {
|
||||
context = new gfxContext(mD2DSurface);
|
||||
nsIntRegionRectIterator iter(aRegion);
|
||||
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
|
||||
context->NewPath();
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
}
|
||||
context->Clip();
|
||||
if (mD2DSurface->GetContentType() != gfxASurface::CONTENT_COLOR) {
|
||||
context->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
context->Paint();
|
||||
context->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
}
|
||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
|
||||
mD2DSurface->Flush();
|
||||
|
||||
// XXX - This call is quite expensive, we may want to consider doing our
|
||||
// drawing in a seperate 'validation' iteration. And then flushing once for
|
||||
// all the D2D surfaces we might have drawn, before doing our D3D9 rendering
|
||||
// loop.
|
||||
cairo_d2d_finish_device(gfxWindowsPlatform::GetPlatform()->GetD2DDevice());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
D3DFORMAT fmt = UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
|
||||
nsIntRect bounds = aRegion.GetBounds();
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatARGB32;
|
||||
nsRefPtr<gfxASurface> destinationSurface;
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> tmpTexture;
|
||||
device()->CreateTexture(bounds.width, bounds.height, 1,
|
||||
0, fmt,
|
||||
D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), NULL);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> surf;
|
||||
HDC dc;
|
||||
if (UseOpaqueSurface(this)) {
|
||||
hr = tmpTexture->GetSurfaceLevel(0, getter_AddRefs(surf));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
// Uh-oh, bail.
|
||||
NS_WARNING("Failed to get texture surface level.");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = surf->GetDC(&dc);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to get device context for texture surface.");
|
||||
return;
|
||||
}
|
||||
|
||||
destinationSurface = new gfxWindowsSurface(dc);
|
||||
} else {
|
||||
// XXX - We may consider retaining a SYSTEMMEM texture texture the size
|
||||
// of our DEFAULT texture and then use UpdateTexture and add dirty rects
|
||||
// to update in a single call.
|
||||
destinationSurface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(bounds.width,
|
||||
bounds.height),
|
||||
imageFormat);
|
||||
}
|
||||
|
||||
context = new gfxContext(destinationSurface);
|
||||
context->Translate(gfxPoint(-bounds.x, -bounds.y));
|
||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
|
||||
|
||||
if (UseOpaqueSurface(this)) {
|
||||
surf->ReleaseDC(dc);
|
||||
} else {
|
||||
D3DLOCKED_RECT r;
|
||||
tmpTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface =
|
||||
new gfxImageSurface((unsigned char *)r.pBits,
|
||||
gfxIntSize(bounds.width,
|
||||
bounds.height),
|
||||
r.Pitch,
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(imgSurface);
|
||||
context->SetSource(destinationSurface);
|
||||
context->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
context->Paint();
|
||||
|
||||
imgSurface = NULL;
|
||||
|
||||
tmpTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> srcSurface;
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
tmpTexture->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
|
||||
|
||||
nsIntRegionRectIterator iter(aRegion);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
RECT rect;
|
||||
rect.left = iterRect->x - bounds.x;
|
||||
rect.top = iterRect->y - bounds.y;
|
||||
rect.right = rect.left + iterRect->width;
|
||||
rect.bottom = rect.top + iterRect->height;
|
||||
POINT point;
|
||||
point.x = iterRect->x - visibleRect.x;
|
||||
point.y = iterRect->y - visibleRect.y;
|
||||
device()->UpdateSurface(srcSurface, &rect, dstSurface, &point);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::CreateNewTexture(const gfxIntSize &aSize)
|
||||
{
|
||||
if (aSize.width == 0 | aSize.height == 0) {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
mTexture = nsnull;
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() ==
|
||||
gfxWindowsPlatform::RENDER_DIRECT2D) {
|
||||
if (mD3DManager->deviceManager()->IsD3D9Ex()) {
|
||||
// We should have D3D9Ex where we have D2D.
|
||||
HANDLE sharedHandle = 0;
|
||||
device()->CreateTexture(aSize.width, aSize.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), &sharedHandle);
|
||||
|
||||
mD2DSurface = new gfxD2DSurface(sharedHandle, UseOpaqueSurface(this) ?
|
||||
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
|
||||
// If there's an error, go on and do what we always do.
|
||||
if (mD2DSurface->CairoStatus()) {
|
||||
mD2DSurface = nsnull;
|
||||
mTexture = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!mTexture) {
|
||||
device()->CreateTexture(aSize.width, aSize.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "LayerManagerD3D9.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -70,6 +69,15 @@ private:
|
|||
* D3D9 texture
|
||||
*/
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
|
||||
/* This contains the D2D surface if we have one */
|
||||
nsRefPtr<gfxASurface> mD2DSurface;
|
||||
|
||||
/* Have a region of our layer drawn */
|
||||
void DrawRegion(const nsIntRegion &aRegion);
|
||||
|
||||
/* Create a new texture */
|
||||
void CreateNewTexture(const gfxIntSize &aSize);
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
|
|
@ -36,10 +36,22 @@
|
|||
#include "gfxD2DSurface.h"
|
||||
#include "cairo.h"
|
||||
#include "cairo-win32.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
||||
gfxD2DSurface::gfxD2DSurface(HWND aWnd, gfxContentType aContent)
|
||||
{
|
||||
Init(cairo_d2d_surface_create_for_hwnd(aWnd, (cairo_content_t)aContent));
|
||||
Init(cairo_d2d_surface_create_for_hwnd(
|
||||
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
|
||||
aWnd,
|
||||
(cairo_content_t)aContent));
|
||||
}
|
||||
|
||||
gfxD2DSurface::gfxD2DSurface(HANDLE handle, gfxContentType aContent)
|
||||
{
|
||||
Init(cairo_d2d_surface_create_for_handle(
|
||||
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
|
||||
handle,
|
||||
(cairo_content_t)aContent));
|
||||
}
|
||||
|
||||
gfxD2DSurface::gfxD2DSurface(cairo_surface_t *csurf)
|
||||
|
@ -50,7 +62,10 @@ gfxD2DSurface::gfxD2DSurface(cairo_surface_t *csurf)
|
|||
gfxD2DSurface::gfxD2DSurface(const gfxIntSize& size,
|
||||
gfxImageFormat imageFormat)
|
||||
{
|
||||
Init(cairo_d2d_surface_create((cairo_format_t)imageFormat, size.width, size.height));
|
||||
Init(cairo_d2d_surface_create(
|
||||
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
|
||||
(cairo_format_t)imageFormat,
|
||||
size.width, size.height));
|
||||
}
|
||||
|
||||
gfxD2DSurface::~gfxD2DSurface()
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
gfxD2DSurface(const gfxIntSize& size,
|
||||
gfxImageFormat imageFormat = ImageFormatRGB24);
|
||||
|
||||
gfxD2DSurface(HANDLE handle, gfxContentType aContent);
|
||||
|
||||
gfxD2DSurface(cairo_surface_t *csurf);
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
|||
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
NS_RegisterMemoryReporter(new D2DCacheReporter());
|
||||
mD2DDevice = NULL;
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
nsresult rv;
|
||||
|
@ -213,7 +214,8 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
|||
#ifndef CAIRO_HAS_D2D_SURFACE
|
||||
return;
|
||||
#else
|
||||
if (!cairo_d2d_has_support()) {
|
||||
mD2DDevice = cairo_d2d_create_device();
|
||||
if (!mD2DDevice) {
|
||||
return;
|
||||
}
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
|
@ -235,6 +237,11 @@ gfxWindowsPlatform::~gfxWindowsPlatform()
|
|||
{
|
||||
// not calling FT_Done_FreeType because cairo may still hold references to
|
||||
// these FT_Faces. See bug 458169.
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
if (mD2DDevice) {
|
||||
cairo_release_device(mD2DDevice);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gfxPlatformFontList*
|
||||
|
|
|
@ -214,6 +214,9 @@ public:
|
|||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; }
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
cairo_device_t *GetD2DDevice() { return mD2DDevice; }
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_FT2_FONTS
|
||||
FT_Library GetFTLibrary();
|
||||
|
@ -233,6 +236,9 @@ private:
|
|||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
nsRefPtr<IDWriteFactory> mDWriteFactory;
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
||||
cairo_device_t *mD2DDevice;
|
||||
#endif
|
||||
|
||||
virtual qcms_profile* GetPlatformCMSOutputProfile();
|
||||
|
||||
|
|
|
@ -131,12 +131,14 @@ void GeckoChildProcessHost::InitWindowsGroupID()
|
|||
#endif
|
||||
|
||||
bool
|
||||
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts)
|
||||
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
InitWindowsGroupID();
|
||||
#endif
|
||||
|
||||
PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ?
|
||||
PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT;
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
|
||||
|
||||
|
@ -144,15 +146,29 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
NewRunnableMethod(this,
|
||||
&GeckoChildProcessHost::PerformAsyncLaunch,
|
||||
aExtraOpts));
|
||||
|
||||
// NB: this uses a different mechanism than the chromium parent
|
||||
// class.
|
||||
MonitorAutoEnter mon(mMonitor);
|
||||
PRIntervalTime waitStart = PR_IntervalNow();
|
||||
PRIntervalTime current;
|
||||
|
||||
// We'll receive several notifications, we need to exit when we
|
||||
// have either successfully launched or have timed out.
|
||||
while (!mLaunched) {
|
||||
mon.Wait();
|
||||
mon.Wait(timeoutTicks);
|
||||
|
||||
if (timeoutTicks != PR_INTERVAL_NO_TIMEOUT) {
|
||||
current = PR_IntervalNow();
|
||||
PRIntervalTime elapsed = current - waitStart;
|
||||
if (elapsed > timeoutTicks) {
|
||||
break;
|
||||
}
|
||||
timeoutTicks = timeoutTicks - elapsed;
|
||||
waitStart = current;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return mLaunched;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
~GeckoChildProcessHost();
|
||||
|
||||
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
|
||||
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(), int32 timeoutMs=0);
|
||||
bool AsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
|
||||
bool PerformAsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ IPDLTESTS = \
|
|||
TestShutdown \
|
||||
TestStackHooks \
|
||||
TestSyncWakeup \
|
||||
TestSyncHang \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
protocol PTestSyncHang {
|
||||
|
||||
child:
|
||||
__delete__();
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
|
@ -0,0 +1,71 @@
|
|||
#include "TestSyncHang.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
mozilla::ipc::GeckoChildProcessHost* gSyncHangSubprocess;
|
||||
|
||||
TestSyncHangParent::TestSyncHangParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestSyncHangParent);
|
||||
}
|
||||
|
||||
TestSyncHangParent::~TestSyncHangParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestSyncHangParent);
|
||||
}
|
||||
|
||||
void
|
||||
DeleteSyncHangSubprocess(MessageLoop* uiLoop)
|
||||
{
|
||||
delete gSyncHangSubprocess;
|
||||
}
|
||||
|
||||
void
|
||||
DeferredSyncHangParentShutdown()
|
||||
{
|
||||
// ping to DeleteSubprocess
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(DeleteSyncHangSubprocess, MessageLoop::current()));
|
||||
}
|
||||
|
||||
void
|
||||
TestSyncHangParent::Main()
|
||||
{
|
||||
vector<string> args;
|
||||
args.push_back("fake/path");
|
||||
gSyncHangSubprocess = new mozilla::ipc::GeckoChildProcessHost(GeckoProcessType_Plugin);
|
||||
bool launched = gSyncHangSubprocess->SyncLaunch(args, 2);
|
||||
if (launched)
|
||||
fail("Calling SyncLaunch with an invalid path should return false");
|
||||
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE, NewRunnableFunction(DeferredSyncHangParentShutdown));
|
||||
Close();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
TestSyncHangChild::TestSyncHangChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestSyncHangChild);
|
||||
}
|
||||
|
||||
TestSyncHangChild::~TestSyncHangChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestSyncHangChild);
|
||||
}
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef mozilla__ipdltest_TestSyncHang_h
|
||||
#define mozilla__ipdltest_TestSyncHang_h 1
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestSyncHangParent.h"
|
||||
#include "mozilla/_ipdltest/PTestSyncHangChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
class TestSyncHangParent :
|
||||
public PTestSyncHangParent
|
||||
{
|
||||
public:
|
||||
TestSyncHangParent();
|
||||
virtual ~TestSyncHangParent();
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TestSyncHangChild :
|
||||
public PTestSyncHangChild
|
||||
{
|
||||
public:
|
||||
TestSyncHangChild();
|
||||
virtual ~TestSyncHangChild();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestSyncHang_h
|
|
@ -30,5 +30,6 @@ IPDLSRCS = \
|
|||
PTestShutdownSubsub.ipdl \
|
||||
PTestStackHooks.ipdl \
|
||||
PTestSyncWakeup.ipdl \
|
||||
PTestSyncHang.ipdl \
|
||||
PTestSysVShmem.ipdl \
|
||||
$(NULL)
|
||||
|
|
|
@ -7611,13 +7611,14 @@ UpdateViewsForTree(nsIFrame* aFrame, nsIViewManager* aViewManager,
|
|||
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
|
||||
|| (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
|
||||
// only do frames that don't have placeholders
|
||||
if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder
|
||||
// get out of flow frame and start over there
|
||||
if (nsGkAtoms::placeholderFrame == child->GetType()) {
|
||||
// do the out-of-flow frame and its continuations
|
||||
nsIFrame* outOfFlowFrame =
|
||||
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
|
||||
|
||||
DoApplyRenderingChangeToTree(outOfFlowFrame, aViewManager,
|
||||
aFrameManager, aChange);
|
||||
do {
|
||||
DoApplyRenderingChangeToTree(outOfFlowFrame, aViewManager,
|
||||
aFrameManager, aChange);
|
||||
} while (outOfFlowFrame = outOfFlowFrame->GetNextContinuation());
|
||||
} else if (childList == nsGkAtoms::popupList) {
|
||||
DoApplyRenderingChangeToTree(child, aViewManager,
|
||||
aFrameManager, aChange);
|
||||
|
|
|
@ -3328,6 +3328,8 @@ DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
|
||||
*aNode = nsnull;
|
||||
|
||||
// get the document
|
||||
nsIDocument* document = GetDocument();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
@ -3340,7 +3342,22 @@ DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode)
|
|||
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
|
||||
|
||||
// get the popup node
|
||||
NS_IF_ADDREF(*aNode = root->GetPopupNode());
|
||||
nsCOMPtr<nsIDOMNode> node = root->GetPopupNode();
|
||||
#ifdef MOZ_XUL
|
||||
if (!node) {
|
||||
nsPIDOMWindow* rootWindow = root->GetWindow();
|
||||
if (rootWindow) {
|
||||
nsCOMPtr<nsIDocument> rootDoc = do_QueryInterface(rootWindow->GetExtantDocument());
|
||||
if (rootDoc) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) {
|
||||
node = pm->GetLastTriggerPopupNode(rootDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
node.swap(*aNode);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mats Palmgren <matspal@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -771,12 +772,13 @@ nsresult
|
|||
nsFrameManager::ReparentStyleContext(nsIFrame* aFrame)
|
||||
{
|
||||
if (nsGkAtoms::placeholderFrame == aFrame->GetType()) {
|
||||
// Also reparent the out-of-flow
|
||||
// Also reparent the out-of-flow and all its continuations.
|
||||
nsIFrame* outOfFlow =
|
||||
nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame);
|
||||
NS_ASSERTION(outOfFlow, "no out-of-flow frame");
|
||||
|
||||
ReparentStyleContext(outOfFlow);
|
||||
do {
|
||||
ReparentStyleContext(outOfFlow);
|
||||
} while (outOfFlow = outOfFlow->GetNextContinuation());
|
||||
}
|
||||
|
||||
// DO NOT verify the style tree before reparenting. The frame
|
||||
|
@ -1470,13 +1472,15 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
|||
|
||||
// |nsFrame::GetParentStyleContextFrame| checks being out
|
||||
// of flow so that this works correctly.
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame,
|
||||
content, aChangeList,
|
||||
NS_SubtractHint(aMinChange,
|
||||
nsChangeHint_ReflowFrame),
|
||||
childRestyleHint,
|
||||
fireAccessibilityEvents,
|
||||
aRestyleTracker);
|
||||
do {
|
||||
ReResolveStyleContext(aPresContext, outOfFlowFrame,
|
||||
content, aChangeList,
|
||||
NS_SubtractHint(aMinChange,
|
||||
nsChangeHint_ReflowFrame),
|
||||
childRestyleHint,
|
||||
fireAccessibilityEvents,
|
||||
aRestyleTracker);
|
||||
} while (outOfFlowFrame = outOfFlowFrame->GetNextContinuation());
|
||||
|
||||
// reresolve placeholder's context under the same parent
|
||||
// as the out-of-flow frame
|
||||
|
|
|
@ -1259,13 +1259,17 @@ pref("editor.positioning.offset", 0);
|
|||
pref("dom.max_chrome_script_run_time", 20);
|
||||
pref("dom.max_script_run_time", 10);
|
||||
|
||||
#ifndef DEBUG
|
||||
// How long a plugin is allowed to process a synchronous IPC message
|
||||
// before we consider it "hung".
|
||||
#ifndef DEBUG
|
||||
pref("dom.ipc.plugins.timeoutSecs", 45);
|
||||
// How long a plugin launch is allowed to take before
|
||||
// we consider it failed.
|
||||
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45);
|
||||
#else
|
||||
// No timeout in DEBUG builds
|
||||
pref("dom.ipc.plugins.timeoutSecs", 0);
|
||||
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 0);
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID
|
||||
|
|
|
@ -142,12 +142,12 @@ static int setupPidLockCleanup;
|
|||
PRCList nsProfileLock::mPidLockList =
|
||||
PR_INIT_STATIC_CLIST(&nsProfileLock::mPidLockList);
|
||||
|
||||
void nsProfileLock::RemovePidLockFiles()
|
||||
void nsProfileLock::RemovePidLockFiles(PRBool aFatalSignal)
|
||||
{
|
||||
while (!PR_CLIST_IS_EMPTY(&mPidLockList))
|
||||
{
|
||||
nsProfileLock *lock = static_cast<nsProfileLock*>(mPidLockList.next);
|
||||
lock->Unlock();
|
||||
lock->Unlock(aFatalSignal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void nsProfileLock::FatalSignalHandler(int signo, siginfo_t *info,
|
|||
void *context)
|
||||
{
|
||||
// Remove any locks still held.
|
||||
RemovePidLockFiles();
|
||||
RemovePidLockFiles(PR_TRUE);
|
||||
|
||||
// Chain to the old handler, which may exit.
|
||||
struct sigaction *oldact = nsnull;
|
||||
|
@ -385,7 +385,7 @@ nsresult nsProfileLock::LockWithSymlink(const nsACString& lockFilePath, PRBool a
|
|||
if (!setupPidLockCleanup++)
|
||||
{
|
||||
// Clean up on normal termination.
|
||||
atexit(RemovePidLockFiles);
|
||||
atexit(RemovePidLockFilesExiting);
|
||||
|
||||
// Clean up on abnormal termination, using POSIX sigaction.
|
||||
// Don't arm a handler if the signal is being ignored, e.g.,
|
||||
|
@ -652,7 +652,7 @@ nsresult nsProfileLock::Lock(nsILocalFile* aProfileDir,
|
|||
}
|
||||
|
||||
|
||||
nsresult nsProfileLock::Unlock()
|
||||
nsresult nsProfileLock::Unlock(PRBool aFatalSignal)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -675,7 +675,14 @@ nsresult nsProfileLock::Unlock()
|
|||
{
|
||||
PR_REMOVE_LINK(this);
|
||||
(void) unlink(mPidLockFileName);
|
||||
free(mPidLockFileName);
|
||||
|
||||
// Only free mPidLockFileName if we're not in the fatal signal
|
||||
// handler. The problem is that a call to free() might be the
|
||||
// cause of this fatal signal. If so, calling free() might cause
|
||||
// us to wait on the malloc implementation's lock. We're already
|
||||
// holding this lock, so we'll deadlock. See bug 522332.
|
||||
if (!aFatalSignal)
|
||||
free(mPidLockFileName);
|
||||
mPidLockFileName = nsnull;
|
||||
}
|
||||
else if (mLockFileDesc != -1)
|
||||
|
|
|
@ -82,7 +82,13 @@ public:
|
|||
* @throws NS_ERROR_FILE_ACCESS_DENIED if the profile is locked.
|
||||
*/
|
||||
nsresult Lock(nsILocalFile* aProfileDir, nsIProfileUnlocker* *aUnlocker);
|
||||
nsresult Unlock();
|
||||
|
||||
/**
|
||||
* Unlock a profile directory. If you're unlocking the directory because
|
||||
* the application is in the process of shutting down because of a fatal
|
||||
* signal, set aFatalSignal to PR_TRUE.
|
||||
*/
|
||||
nsresult Unlock(PRBool aFatalSignal = PR_FALSE);
|
||||
|
||||
private:
|
||||
PRPackedBool mHaveLock;
|
||||
|
@ -92,7 +98,17 @@ private:
|
|||
#elif defined (XP_OS2)
|
||||
LHANDLE mLockFileHandle;
|
||||
#elif defined (XP_UNIX)
|
||||
static void RemovePidLockFiles();
|
||||
|
||||
static void RemovePidLockFilesExiting()
|
||||
{
|
||||
// We can't implement this function with a default parameter on
|
||||
// RemovePidLockFiles(aFatalSignal) since we register
|
||||
// atexit(RemovePidLockFilesExiting).
|
||||
|
||||
RemovePidLockFiles(PR_FALSE);
|
||||
}
|
||||
|
||||
static void RemovePidLockFiles(PRBool aFatalSignal);
|
||||
static void FatalSignalHandler(int signo, siginfo_t *info,
|
||||
void *context);
|
||||
static PRCList mPidLockList;
|
||||
|
|
|
@ -2485,8 +2485,10 @@ JSTerm.prototype = {
|
|||
this.createSandbox();
|
||||
this.inputNode = this.mixins.inputNode;
|
||||
this.scrollToNode = this.mixins.scrollToNode;
|
||||
let eventHandler = this.keyDown();
|
||||
this.inputNode.addEventListener('keypress', eventHandler, false);
|
||||
let eventHandlerKeyDown = this.keyDown();
|
||||
this.inputNode.addEventListener('keypress', eventHandlerKeyDown, false);
|
||||
let eventHandlerInput = this.inputEventHandler();
|
||||
this.inputNode.addEventListener('input', eventHandlerInput, false);
|
||||
this.outputNode = this.mixins.outputNode;
|
||||
if (this.mixins.cssClassOverride) {
|
||||
this.cssClassOverride = this.mixins.cssClassOverride;
|
||||
|
@ -2614,6 +2616,16 @@ JSTerm.prototype = {
|
|||
outputNode.lastTimestamp = 0;
|
||||
},
|
||||
|
||||
inputEventHandler: function JSTF_inputEventHandler()
|
||||
{
|
||||
var self = this;
|
||||
function handleInputEvent(aEvent) {
|
||||
self.inputNode.setAttribute("rows",
|
||||
Math.min(8, self.inputNode.value.split("\n").length));
|
||||
}
|
||||
return handleInputEvent;
|
||||
},
|
||||
|
||||
keyDown: function JSTF_keyDown(aEvent)
|
||||
{
|
||||
var self = this;
|
||||
|
@ -2657,6 +2669,7 @@ JSTerm.prototype = {
|
|||
case 13:
|
||||
// return
|
||||
self.execute();
|
||||
aEvent.preventDefault();
|
||||
break;
|
||||
case 38:
|
||||
// up arrow: history previous
|
||||
|
@ -2771,7 +2784,7 @@ JSTerm.prototype = {
|
|||
{
|
||||
var firstLineBreak = this.codeInputString.indexOf("\n");
|
||||
return ((firstLineBreak == -1) ||
|
||||
(this.codeInputString.selectionStart <= firstLineBreak));
|
||||
(this.inputNode.selectionStart <= firstLineBreak));
|
||||
},
|
||||
|
||||
caretInLastLine: function JSTF_caretInLastLine()
|
||||
|
@ -2951,6 +2964,8 @@ JSTermFirefoxMixin.prototype = {
|
|||
{
|
||||
let inputNode = this.xulElementFactory("textbox");
|
||||
inputNode.setAttribute("class", "jsterm-input-node");
|
||||
inputNode.setAttribute("multiline", "true");
|
||||
inputNode.setAttribute("rows", "1");
|
||||
|
||||
if (this.existingConsoleNode == undefined) {
|
||||
// create elements
|
||||
|
|
|
@ -573,6 +573,39 @@ function testCompletion()
|
|||
is(input.selectionEnd, 23, "end selection is alright");
|
||||
}
|
||||
|
||||
function testJSInputExpand()
|
||||
{
|
||||
let HUD = HUDService.hudWeakReferences[hudId].get();
|
||||
let jsterm = HUD.jsterm;
|
||||
let input = jsterm.inputNode;
|
||||
input.focus();
|
||||
|
||||
is(input.getAttribute("multiline"), "true", "multiline is enabled");
|
||||
|
||||
// Tests if the inputNode expands.
|
||||
input.value = "hello\nworld\n";
|
||||
let length = input.value.length;
|
||||
input.selectionEnd = length;
|
||||
input.selectionStart = length;
|
||||
// Performs an "d". This will trigger/test for the input event that should
|
||||
// change the "row" attribute of the inputNode.
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
is(input.getAttribute("rows"), "3", "got 3 rows");
|
||||
|
||||
// Add some more rows. Tests for the 8 row limit.
|
||||
input.value = "row1\nrow2\nrow3\nrow4\nrow5\nrow6\nrow7\nrow8\nrow9\nrow10\n";
|
||||
length = input.value.length;
|
||||
input.selectionEnd = length;
|
||||
input.selectionStart = length;
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
is(input.getAttribute("rows"), "8", "got 8 rows");
|
||||
|
||||
// Test if the inputNode shrinks again.
|
||||
input.value = "";
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
is(input.getAttribute("rows"), "1", "got 1 row");
|
||||
}
|
||||
|
||||
function testExecutionScope()
|
||||
{
|
||||
content.location.href = TEST_URI;
|
||||
|
@ -844,6 +877,7 @@ function test() {
|
|||
testExecutionScope();
|
||||
testCompletion();
|
||||
testPropertyProvider();
|
||||
testJSInputExpand();
|
||||
testNet();
|
||||
});
|
||||
}, false);
|
||||
|
|
|
@ -157,6 +157,10 @@
|
|||
-moz-appearance: none !important;
|
||||
}
|
||||
|
||||
.jsterm-input-node textarea {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.jsterm-output-line {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
|
|
@ -156,6 +156,10 @@
|
|||
-moz-appearance: none !important;
|
||||
}
|
||||
|
||||
.jsterm-input-node textarea {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.jsterm-output-line {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,10 @@ nsSystemInfo::SetInt32Property(const nsAString &aPropertyName,
|
|||
{
|
||||
NS_WARN_IF_FALSE(aValue > 0, "Unable to read system value");
|
||||
if (aValue > 0) {
|
||||
nsresult rv = SetPropertyAsInt32(aPropertyName, aValue);
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
#endif
|
||||
SetPropertyAsInt32(aPropertyName, aValue);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to set property");
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +147,10 @@ nsSystemInfo::SetUint64Property(const nsAString &aPropertyName,
|
|||
{
|
||||
NS_WARN_IF_FALSE(aValue > 0, "Unable to read system value");
|
||||
if (aValue > 0) {
|
||||
nsresult rv = SetPropertyAsUint64(aPropertyName, aValue);
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
#endif
|
||||
SetPropertyAsUint64(aPropertyName, aValue);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to set property");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,10 @@ const char* AssertEqual(PRInt32 aValue1, PRInt32 aValue2)
|
|||
void DumpArray(nsISupportsArray* aArray, PRInt32 aExpectedCount, PRInt32 aElementIDs[], PRInt32 aExpectedTotal)
|
||||
{
|
||||
PRUint32 cnt = 0;
|
||||
nsresult rv = aArray->Count(&cnt);
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
#endif
|
||||
aArray->Count(&cnt);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
||||
PRInt32 count = cnt;
|
||||
PRInt32 index;
|
||||
|
|
|
@ -61,8 +61,15 @@ PRIntn sign(PRIntn val) {
|
|||
// iso-latin-1 strings, so the comparison must be valid.
|
||||
static void Check(const char* s1, const char* s2, PRIntn n)
|
||||
{
|
||||
PRIntn clib = PL_strcmp(s1, s2);
|
||||
PRIntn clib_n = PL_strncmp(s1, s2, n);
|
||||
#ifdef DEBUG
|
||||
PRIntn clib =
|
||||
#endif
|
||||
PL_strcmp(s1, s2);
|
||||
|
||||
#ifdef DEBUG
|
||||
PRIntn clib_n =
|
||||
#endif
|
||||
PL_strncmp(s1, s2, n);
|
||||
|
||||
nsAutoString t1,t2;
|
||||
t1.AssignWithConversion(s1);
|
||||
|
@ -70,8 +77,15 @@ static void Check(const char* s1, const char* s2, PRIntn n)
|
|||
const PRUnichar* us1 = t1.get();
|
||||
const PRUnichar* us2 = t2.get();
|
||||
|
||||
PRIntn u2 = nsCRT::strcmp(us1, us2);
|
||||
PRIntn u2_n = nsCRT::strncmp(us1, us2, n);
|
||||
#ifdef DEBUG
|
||||
PRIntn u2 =
|
||||
#endif
|
||||
nsCRT::strcmp(us1, us2);
|
||||
|
||||
#ifdef DEBUG
|
||||
PRIntn u2_n =
|
||||
#endif
|
||||
nsCRT::strncmp(us1, us2, n);
|
||||
|
||||
NS_ASSERTION(sign(clib) == sign(u2), "strcmp");
|
||||
NS_ASSERTION(sign(clib_n) == sign(u2_n), "strncmp");
|
||||
|
|
|
@ -327,7 +327,11 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
|
|||
//printf("calling Flush\n");
|
||||
out->Flush();
|
||||
//printf("calling WaitForReceipt\n");
|
||||
const PRUint32 received = receiver->WaitForReceipt(writeCount);
|
||||
|
||||
#ifdef DEBUG
|
||||
const PRUint32 received =
|
||||
#endif
|
||||
receiver->WaitForReceipt(writeCount);
|
||||
NS_ASSERTION(received == writeCount, "received wrong amount");
|
||||
}
|
||||
rv = out->Close();
|
||||
|
|
Загрузка…
Ссылка в новой задаче