mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
b63e497f2a
@ -3640,11 +3640,11 @@ GetExtendedOrigin(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
|
||||
return;
|
||||
}
|
||||
|
||||
// aExtendedOrigin = origin + "@" + aAppId + { 't', 'f' }
|
||||
aExtendedOrigin.Assign(origin + NS_LITERAL_CSTRING("@"));
|
||||
// aExtendedOrigin = appId + "+" + origin + "+" + { 't', 'f' }
|
||||
aExtendedOrigin.Truncate();
|
||||
aExtendedOrigin.AppendInt(aAppId);
|
||||
aExtendedOrigin.Append(aInMozBrowser ? NS_LITERAL_CSTRING("t")
|
||||
: NS_LITERAL_CSTRING("f"));
|
||||
aExtendedOrigin.Append(NS_LITERAL_CSTRING("+") + origin + NS_LITERAL_CSTRING("+"));
|
||||
aExtendedOrigin.Append(aInMozBrowser ? 't' : 'f');
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -18,9 +18,11 @@ MOCHITEST_FILES = test_bug423375.html \
|
||||
test_disallowInheritPrincipal.html \
|
||||
$(NULL)
|
||||
|
||||
# Temporarily disabled for orange
|
||||
# MOCHITEST_CHROME_FILES = test_principal_extendedorigin_appid_appstatus.html \
|
||||
# $(NULL)
|
||||
# extendedOrigin test doesn't work on Windows, see bug 776296.
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
MOCHITEST_CHROME_FILES = test_principal_extendedorigin_appid_appstatus.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
test_bug292789.html : % : %.in
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
|
@ -16,7 +16,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=758258
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
/** Test for Bug 758258 **/
|
||||
|
||||
@ -105,7 +105,6 @@ var gData = [
|
||||
browser: true,
|
||||
test: [ "eo-as-last" ],
|
||||
},
|
||||
/*
|
||||
// {
|
||||
// app: "http://example.org/manifest.webapp",
|
||||
// src: "data:text/html,foobar",
|
||||
@ -116,14 +115,13 @@ var gData = [
|
||||
// src: "data:text/html,foobar2",
|
||||
// test: [ "todo-src" ],
|
||||
// },
|
||||
*/
|
||||
{
|
||||
src: "file:///",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
{
|
||||
src: "file:///tmp",
|
||||
src: "file:///tmp/",
|
||||
isapp: false,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
@ -135,10 +133,127 @@ var gData = [
|
||||
},
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "file:///tmp",
|
||||
src: "file:///tmp/",
|
||||
isapp: true,
|
||||
test: [ "eo-unique" ],
|
||||
},
|
||||
// iframe inside an app is part of the app.
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/",
|
||||
isapp: true,
|
||||
child: {
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: true
|
||||
},
|
||||
test: [ "child-has-same-eo" ],
|
||||
},
|
||||
// app A inside app B aren't the same app.
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/",
|
||||
isapp: true,
|
||||
child: {
|
||||
app: "https://example.com/manifest.webapp",
|
||||
src: "https://example.com/chrome/",
|
||||
isapp: true
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-different-appid" ],
|
||||
},
|
||||
// app A inside app A are the same app.
|
||||
{
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/",
|
||||
isapp: true,
|
||||
child: {
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: true
|
||||
},
|
||||
test: [ "child-has-same-eo" ],
|
||||
},
|
||||
// app inside a regular iframe is an app.
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
child: {
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: true
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-different-appid" ],
|
||||
},
|
||||
// browser inside app is a browser, has appid but isn't installed.
|
||||
{
|
||||
src: "http://example.org/",
|
||||
app: "http://example.org/manifest.webapp",
|
||||
isapp: true,
|
||||
child: {
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-same-appid" ],
|
||||
},
|
||||
// app inside a browser is an app.
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
child: {
|
||||
app: "http://example.org/manifest.webapp",
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: true,
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-different-appid" ],
|
||||
},
|
||||
// browser inside a browser are two browsers
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
child: {
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
},
|
||||
test: [ "child-has-same-eo" ],
|
||||
},
|
||||
// browser inside a browser are two browsers
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
child: {
|
||||
src: "https://example.com/chrome/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-same-appid" ],
|
||||
},
|
||||
// iframe containing a browser
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
browser: false,
|
||||
child: {
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
},
|
||||
test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-same-appid" ],
|
||||
},
|
||||
// browser containing an iframe is part of the browser
|
||||
{
|
||||
src: "http://example.org/",
|
||||
isapp: false,
|
||||
browser: true,
|
||||
child: {
|
||||
src: "http://example.org/chrome/",
|
||||
isapp: false,
|
||||
},
|
||||
test: [ "child-has-same-eo" ],
|
||||
},
|
||||
];
|
||||
|
||||
// The list of all data ids generated by this test.
|
||||
@ -148,16 +263,21 @@ var content = document.getElementById('content');
|
||||
var checkedCount = 0;
|
||||
var checksTodo = gData.length;
|
||||
|
||||
function checkPrincipalForIFrame(aFrame, data) {
|
||||
function checkIFrame(aFrame, data) {
|
||||
var principal = aFrame.contentDocument.nodePrincipal;
|
||||
|
||||
if (!data.test) {
|
||||
data.test = [];
|
||||
}
|
||||
|
||||
// Temporarily disable that check.
|
||||
// is(principal.URI.spec, data.src,
|
||||
// 'the correct URL should have been loaded');
|
||||
if (navigator.platform.indexOf("Mac") != -1) {
|
||||
is(principal.URI.spec,
|
||||
data.src.replace('file:///tmp/', 'file:///private/tmp/'),
|
||||
'the correct URL should have been loaded');
|
||||
} else {
|
||||
is(principal.URI.spec, data.src,
|
||||
'the correct URL should have been loaded');
|
||||
}
|
||||
|
||||
if (data.isapp) {
|
||||
is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
@ -190,11 +310,56 @@ function checkPrincipalForIFrame(aFrame, data) {
|
||||
"extendedOrigin should be the same as the last inserted one");
|
||||
}
|
||||
|
||||
if (data.child) {
|
||||
let childPrincipal = aFrame.contentWindow.frames[0].document.nodePrincipal;
|
||||
|
||||
if (data.child.isapp) {
|
||||
is(childPrincipal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
"child should be an installed app");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-same-eo") != -1) {
|
||||
is(childPrincipal.extendedOrigin, principal.extendedOrigin,
|
||||
"child should have the same extendedOrigin as parent");
|
||||
is(childPrincipal.appStatus, principal.appStatus,
|
||||
"child should have the same appStatus if it has the same extendedOrigin");
|
||||
is(childPrincipal.appId, principal.appId,
|
||||
"child should have the same appId if it has the same extendedOrigin");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-different-eo") != -1) {
|
||||
isnot(childPrincipal.extendedOrigin, principal.extendedOrigin,
|
||||
"child should not have the same extendedOrigin as parent");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-same-appstatus") != -1) {
|
||||
is(childPrincipal.appStatus, principal.appStatus,
|
||||
"childPrincipal and parent principal should have the same appStatus");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-different-appstatus") != -1) {
|
||||
isnot(childPrincipal.appStatus, principal.appStatus,
|
||||
"childPrincipal and parent principal should not have the same appStatus");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-same-appid") != -1) {
|
||||
is(childPrincipal.appId, principal.appId,
|
||||
"childPrincipal and parent principal should have the same appId");
|
||||
}
|
||||
|
||||
if (data.test.indexOf("child-has-different-appid") != -1) {
|
||||
isnot(childPrincipal.appId, principal.appId,
|
||||
"childPrincipal and parent principal should have different appId");
|
||||
}
|
||||
}
|
||||
|
||||
eoList.push(principal.extendedOrigin);
|
||||
|
||||
checkedCount++;
|
||||
if (checkedCount == checksTodo) {
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
gTestRunner.next();
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,35 +370,60 @@ is('extendedOrigin' in document.nodePrincipal, true,
|
||||
is('appId' in document.nodePrincipal, true,
|
||||
'appId should be present in nsIPrincipal');
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true]]}, function() {
|
||||
function runTest() {
|
||||
// We want to use a generator. Those only work in a one level stack so we
|
||||
// can't use .forEach() here.
|
||||
for (var i=0; i<gData.length; ++i) {
|
||||
let data = gData[i];
|
||||
|
||||
// For some unknown reasons, this test this to always timeout on Windows.
|
||||
if (navigator.platform.indexOf("Win") != -1) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.check = function() {
|
||||
checkIFrame(this, data);
|
||||
};
|
||||
iframe.addChild = function() {
|
||||
var childFrame = document.createElement('iframe');
|
||||
|
||||
if (data.child.app) {
|
||||
childFrame.setAttribute('mozapp', data.child.app)
|
||||
childFrame.setAttribute('mozbrowser', '');
|
||||
} else if (data.child.browser) {
|
||||
childFrame.setAttribute('mozbrowser', '');
|
||||
}
|
||||
|
||||
childFrame.src = data.child.src;
|
||||
|
||||
this.removeEventListener('load', this.addChild.bind(this));
|
||||
childFrame.addEventListener('load', this.check.bind(this));
|
||||
|
||||
this.contentDocument.body.appendChild(childFrame);
|
||||
};
|
||||
|
||||
if (data.app) {
|
||||
iframe.setAttribute('mozapp', data.app);
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
} else if (data.browser) {
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
}
|
||||
|
||||
iframe.src = data.src;
|
||||
|
||||
if (data.child) {
|
||||
iframe.addEventListener('load', iframe.addChild.bind(iframe));
|
||||
} else {
|
||||
iframe.addEventListener('load', iframe.check.bind(iframe));
|
||||
}
|
||||
|
||||
content.appendChild(iframe);
|
||||
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
gData.forEach(function(data) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.checkPrincipal = function() {
|
||||
checkPrincipalForIFrame(this, data);
|
||||
};
|
||||
var gTestRunner = runTest();
|
||||
|
||||
if (data.app) {
|
||||
iframe.setAttribute('mozapp', data.app);
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
} else if (data.browser) {
|
||||
iframe.setAttribute('mozbrowser', '');
|
||||
}
|
||||
|
||||
iframe.src = data.src;
|
||||
|
||||
iframe.addEventListener('load', iframe.checkPrincipal.bind(iframe));
|
||||
|
||||
content.appendChild(iframe);
|
||||
});
|
||||
|
||||
});
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.mozBrowserFramesWhitelist", "http://example.org"]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -1597,7 +1597,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
EnsureMessageManager();
|
||||
|
||||
if (OwnerIsBrowserFrame()) {
|
||||
mDocShell->SetIsBrowser();
|
||||
mDocShell->SetIsBrowserElement();
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
@ -1971,6 +1971,31 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
return false;
|
||||
}
|
||||
|
||||
PRUint32 appId = 0;
|
||||
bool isBrowserElement = false;
|
||||
|
||||
if (OwnerIsBrowserFrame()) {
|
||||
isBrowserElement = true;
|
||||
|
||||
if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)) {
|
||||
nsAutoString manifest;
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifest);
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (!appsService) {
|
||||
NS_ERROR("Apps Service is not available!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
appsService->GetAppLocalIdByManifestURL(manifest, &appId);
|
||||
|
||||
// If the frame is actually an app, we should not mark it as a browser.
|
||||
if (appId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
isBrowserElement = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If our owner has no app manifest URL, then this is equivalent to
|
||||
// ContentParent::GetNewOrUsed().
|
||||
nsAutoString appManifest;
|
||||
@ -1978,8 +2003,7 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
ContentParent* parent = ContentParent::GetForApp(appManifest);
|
||||
|
||||
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
|
||||
mRemoteBrowser = parent->CreateTab(chromeFlags,
|
||||
/* aIsBrowserFrame = */ OwnerIsBrowserFrame());
|
||||
mRemoteBrowser = parent->CreateTab(chromeFlags, isBrowserElement, appId);
|
||||
if (mRemoteBrowser) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser->SetOwnerElement(element);
|
||||
|
@ -68,7 +68,7 @@ nsSVGSwitchElement::MaybeInvalidate()
|
||||
|
||||
nsIFrame *frame = GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(frame);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(frame);
|
||||
}
|
||||
|
||||
mActiveChild = newActiveChild;
|
||||
|
@ -11992,7 +11992,7 @@ nsDocShell::GetCanExecuteScripts(bool *aResult)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsBrowser()
|
||||
nsDocShell::SetIsBrowserElement()
|
||||
{
|
||||
if (mIsBrowserFrame) {
|
||||
NS_ERROR("You should not call SetIsBrowser() more than once.");
|
||||
|
@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
|
||||
interface nsIVariant;
|
||||
interface nsIPrivacyTransitionObserver;
|
||||
|
||||
[scriptable, builtinclass, uuid(ef5a9aba-fe75-410c-a216-fe9b71a6661c)]
|
||||
[scriptable, builtinclass, uuid(be5a675b-b675-4443-af75-510530eab5fa)]
|
||||
interface nsIDocShell : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -584,7 +584,7 @@ interface nsIDocShell : nsISupports
|
||||
*
|
||||
* This method should not be called more than once.
|
||||
*/
|
||||
void setIsBrowser();
|
||||
void setIsBrowserElement();
|
||||
|
||||
/**
|
||||
* Returns true iff the docshell is marked as a browser frame.
|
||||
|
@ -59,7 +59,6 @@ BrowserElementChild.prototype = {
|
||||
|
||||
BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
|
||||
|
||||
docShell.setIsBrowser();
|
||||
docShell.QueryInterface(Ci.nsIWebProgress)
|
||||
.addProgressListener(this._progressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION |
|
||||
|
@ -396,9 +396,11 @@ ContentChild::AllocPCompositor(ipc::Transport* aTransport,
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
|
||||
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId)
|
||||
{
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserFrame);
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement, aAppId);
|
||||
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ public:
|
||||
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserFrame);
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId);
|
||||
virtual bool DeallocPBrowser(PBrowserChild*);
|
||||
|
||||
virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);
|
||||
|
@ -430,9 +430,9 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
|
||||
TabParent*
|
||||
ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame)
|
||||
ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId)
|
||||
{
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserFrame));
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserElement, aAppId));
|
||||
}
|
||||
|
||||
void
|
||||
@ -834,7 +834,9 @@ ContentParent::AllocPCompositor(ipc::Transport* aTransport,
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
|
||||
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId)
|
||||
{
|
||||
TabParent* parent = new TabParent();
|
||||
if (parent){
|
||||
|
@ -69,10 +69,11 @@ public:
|
||||
/**
|
||||
* Create a new tab.
|
||||
*
|
||||
* |aIsBrowserFrame| indicates whether this tab is part of an
|
||||
* |aIsBrowserElement| indicates whether this tab is part of an
|
||||
* <iframe mozbrowser>.
|
||||
* |aAppId| indicates which app the tab belongs to.
|
||||
*/
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame);
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId);
|
||||
/** Notify that a tab was destroyed during normal operation. */
|
||||
void NotifyTabDestroyed(PBrowserParent* aTab);
|
||||
|
||||
@ -132,7 +133,7 @@ private:
|
||||
PCompositorParent* AllocPCompositor(ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame);
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserElement, const PRUint32& aAppId);
|
||||
virtual bool DeallocPBrowser(PBrowserParent* frame);
|
||||
|
||||
virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);
|
||||
|
@ -120,7 +120,7 @@ both:
|
||||
// The child creates the PBrowser as part of
|
||||
// TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
|
||||
// as part of ContentParent::CreateTab.
|
||||
async PBrowser(PRUint32 chromeFlags, bool isBrowserFrame);
|
||||
async PBrowser(PRUint32 chromeFlags, bool isBrowserElement, PRUint32 appId);
|
||||
|
||||
child:
|
||||
PMemoryReportRequest();
|
||||
|
@ -88,14 +88,16 @@ public:
|
||||
};
|
||||
|
||||
|
||||
TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame)
|
||||
TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserElement,
|
||||
PRUint32 aAppId)
|
||||
: mRemoteFrame(nsnull)
|
||||
, mTabChildGlobal(nsnull)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mOuterRect(0, 0, 0, 0)
|
||||
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
||||
, mDidFakeShow(false)
|
||||
, mIsBrowserFrame(aIsBrowserFrame)
|
||||
, mIsBrowserElement(aIsBrowserElement)
|
||||
, mAppId(aAppId)
|
||||
{
|
||||
printf("creating %d!\n", NS_IsMainThread());
|
||||
}
|
||||
@ -380,8 +382,7 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
|
||||
nsRefPtr<TabChild> newChild =
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
|
||||
/* aChromeFlags = */ 0,
|
||||
/* aIsBrowserFrame = */ true));
|
||||
/* aChromeFlags = */ 0, mIsBrowserElement, mAppId));
|
||||
|
||||
nsCAutoString spec;
|
||||
aURI->GetSpec(spec);
|
||||
@ -584,6 +585,17 @@ TabChild::RecvShow(const nsIntSize& size)
|
||||
baseWindow->InitWindow(0, mWidget,
|
||||
0, 0, size.width, size.height);
|
||||
baseWindow->Create();
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWebNav);
|
||||
MOZ_ASSERT(docShell);
|
||||
|
||||
if (docShell) {
|
||||
docShell->SetAppId(mAppId);
|
||||
if (mIsBrowserElement) {
|
||||
docShell->SetIsBrowserElement();
|
||||
}
|
||||
}
|
||||
|
||||
baseWindow->SetVisibility(true);
|
||||
|
||||
// IPC uses a WebBrowser object for which DNS prefetching is turned off
|
||||
@ -1043,7 +1055,7 @@ TabChild::InitTabChildGlobal()
|
||||
root->SetParentTarget(scope);
|
||||
|
||||
// Initialize the child side of the browser element machinery, if appropriate.
|
||||
if (mIsBrowserFrame) {
|
||||
if (mIsBrowserElement || mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
RecvLoadRemoteScript(
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"));
|
||||
}
|
||||
|
@ -147,10 +147,11 @@ public:
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*
|
||||
* |aIsBrowserFrame| indicates whether the TabChild is inside an
|
||||
* <iframe mozbrowser>.
|
||||
* |aIsBrowserElement| indicates whether the tab is inside an <iframe mozbrowser>.
|
||||
* |aAppId| is the app id of the app containing this tab. If the tab isn't
|
||||
* contained in an app, aAppId will be nsIScriptSecurityManager::NO_APP_ID.
|
||||
*/
|
||||
TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame);
|
||||
TabChild(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId);
|
||||
virtual ~TabChild();
|
||||
nsresult Init();
|
||||
|
||||
@ -304,7 +305,8 @@ private:
|
||||
nscolor mLastBackgroundColor;
|
||||
ScrollingBehavior mScrolling;
|
||||
bool mDidFakeShow;
|
||||
bool mIsBrowserFrame;
|
||||
bool mIsBrowserElement;
|
||||
PRUint32 mAppId;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
// must include config.h first for webkit to fiddle with new/delete
|
||||
#include <android/log.h>
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidMediaLayer.h"
|
||||
#include "ANPBase.h"
|
||||
#include "nsIPluginInstanceOwner.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
@ -18,14 +19,29 @@ using namespace mozilla;
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||
#define ASSIGN(obj, name) (obj)->name = anp_native_window_##name
|
||||
|
||||
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
|
||||
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
return pinst->AcquireContentWindow();
|
||||
|
||||
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
|
||||
}
|
||||
|
||||
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
|
||||
nsRefPtr<nsPluginInstanceOwner> owner;
|
||||
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
|
||||
return NULL;
|
||||
|
||||
ANPNativeWindow window = owner->Layer()->GetNativeWindowForContent();
|
||||
owner->Invalidate();
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void anp_native_window_invertPluginContent(NPP instance, bool isContentInverted) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
pinst->SetInverted(isContentInverted);
|
||||
nsRefPtr<nsPluginInstanceOwner> owner;
|
||||
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
|
||||
return;
|
||||
|
||||
owner->Layer()->SetInverted(isContentInverted);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "ANPBase.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||
#define ASSIGN(obj, name) (obj)->name = anp_opengl_##name
|
||||
@ -17,53 +15,24 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
typedef nsNPAPIPluginInstance::TextureInfo TextureInfo;
|
||||
|
||||
static ANPEGLContext anp_opengl_acquireContext(NPP instance) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
|
||||
GLContext* context = pinst->GLContext();
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
context->MakeCurrent();
|
||||
return context->GetNativeData(GLContext::NativeGLContext);
|
||||
static ANPEGLContext anp_opengl_acquireContext(NPP inst) {
|
||||
// Bug 687267
|
||||
NOT_IMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ANPTextureInfo anp_opengl_lockTexture(NPP instance) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
|
||||
TextureInfo pluginInfo = pinst->LockContentTexture();
|
||||
|
||||
ANPTextureInfo info;
|
||||
info.textureId = pluginInfo.mTexture;
|
||||
info.width = pluginInfo.mWidth;
|
||||
info.height = pluginInfo.mHeight;
|
||||
|
||||
// It looks like we should be passing whatever
|
||||
// internal format Flash told us it used previously
|
||||
// (e.g., the value of pluginInfo.mInternalFormat),
|
||||
// but if we do that it doesn't upload to the texture
|
||||
// for some reason.
|
||||
info.internalFormat = 0;
|
||||
|
||||
ANPTextureInfo info = { 0, 0, 0, 0 };
|
||||
NOT_IMPLEMENTED();
|
||||
return info;
|
||||
}
|
||||
|
||||
static void anp_opengl_releaseTexture(NPP instance, const ANPTextureInfo* info) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
|
||||
TextureInfo pluginInfo(info->textureId, info->width, info->height, info->internalFormat);
|
||||
pinst->ReleaseContentTexture(pluginInfo);
|
||||
pinst->RedrawPlugin();
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
static void anp_opengl_invertPluginContent(NPP instance, bool isContentInverted) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
|
||||
// Our definition of inverted is the opposite of the plugin's
|
||||
pinst->SetInverted(!isContentInverted);
|
||||
pinst->RedrawPlugin();
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3,8 +3,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <android/log.h>
|
||||
#include "AndroidBridge.h"
|
||||
#include "ANPBase.h"
|
||||
#include "AndroidMediaLayer.h"
|
||||
#include "nsIPluginInstanceOwner.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
@ -15,30 +15,58 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
|
||||
|
||||
static ANPNativeWindow anp_video_acquireNativeWindow(NPP instance) {
|
||||
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
|
||||
return pinst->AcquireVideoWindow();
|
||||
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
|
||||
}
|
||||
|
||||
static AndroidMediaLayer* GetLayerForInstance(NPP instance) {
|
||||
nsRefPtr<nsPluginInstanceOwner> owner;
|
||||
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
|
||||
return NULL;
|
||||
|
||||
return owner->Layer();
|
||||
}
|
||||
|
||||
static void Invalidate(NPP instance) {
|
||||
nsRefPtr<nsPluginInstanceOwner> owner;
|
||||
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
|
||||
return;
|
||||
|
||||
owner->Invalidate();
|
||||
}
|
||||
|
||||
static ANPNativeWindow anp_video_acquireNativeWindow(NPP instance) {
|
||||
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||
if (!layer)
|
||||
return NULL;
|
||||
|
||||
return layer->RequestNativeWindowForVideo();
|
||||
}
|
||||
|
||||
static void anp_video_setWindowDimensions(NPP instance, const ANPNativeWindow window,
|
||||
const ANPRectF* dimensions) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
const ANPRectF* dimensions) {
|
||||
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
gfxRect rect(dimensions->left, dimensions->top,
|
||||
dimensions->right - dimensions->left,
|
||||
dimensions->bottom - dimensions->top);
|
||||
|
||||
pinst->SetVideoDimensions(window, rect);
|
||||
pinst->RedrawPlugin();
|
||||
layer->SetNativeWindowDimensions(window, rect);
|
||||
Invalidate(instance);
|
||||
}
|
||||
|
||||
|
||||
static void anp_video_releaseNativeWindow(NPP instance, ANPNativeWindow window) {
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
pinst->ReleaseVideoWindow(window);
|
||||
pinst->RedrawPlugin();
|
||||
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
layer->ReleaseNativeWindowForVideo(window);
|
||||
Invalidate(instance);
|
||||
}
|
||||
|
||||
static void anp_video_setFramerateCallback(NPP instance, const ANPNativeWindow window, ANPVideoFrameCallbackProc callback) {
|
||||
|
@ -42,14 +42,6 @@
|
||||
#include "AndroidBridge.h"
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "TexturePoolOGL.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
typedef nsNPAPIPluginInstance::TextureInfo TextureInfo;
|
||||
typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
|
||||
|
||||
class PluginEventRunnable : public nsRunnable
|
||||
{
|
||||
@ -73,89 +65,6 @@ private:
|
||||
bool mCanceled;
|
||||
};
|
||||
|
||||
static nsRefPtr<GLContext> sPluginContext = nsnull;
|
||||
|
||||
static bool EnsureGLContext()
|
||||
{
|
||||
if (!sPluginContext) {
|
||||
sPluginContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16));
|
||||
}
|
||||
|
||||
return sPluginContext != nsnull;
|
||||
}
|
||||
|
||||
class SharedPluginTexture {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(SharedPluginTexture)
|
||||
|
||||
SharedPluginTexture() :
|
||||
mCurrentHandle(0), mNeedNewImage(false), mLock("SharedPluginTexture.mLock")
|
||||
{
|
||||
}
|
||||
|
||||
~SharedPluginTexture()
|
||||
{
|
||||
// This will be destroyed in the compositor (as it normally is)
|
||||
mCurrentHandle = nsnull;
|
||||
}
|
||||
|
||||
TextureInfo Lock()
|
||||
{
|
||||
if (!EnsureGLContext()) {
|
||||
mTextureInfo.mTexture = 0;
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
if (!mTextureInfo.mTexture && sPluginContext->MakeCurrent()) {
|
||||
sPluginContext->fGenTextures(1, &mTextureInfo.mTexture);
|
||||
}
|
||||
|
||||
mLock.Lock();
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
void Release(TextureInfo& aTextureInfo)
|
||||
{
|
||||
mNeedNewImage = true;
|
||||
|
||||
mTextureInfo = aTextureInfo;
|
||||
mLock.Unlock();
|
||||
}
|
||||
|
||||
SharedTextureHandle CreateSharedHandle()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
if (!mNeedNewImage)
|
||||
return mCurrentHandle;
|
||||
|
||||
if (!EnsureGLContext())
|
||||
return nsnull;
|
||||
|
||||
mNeedNewImage = false;
|
||||
|
||||
if (mTextureInfo.mWidth == 0 || mTextureInfo.mHeight == 0)
|
||||
return nsnull;
|
||||
|
||||
mCurrentHandle = sPluginContext->CreateSharedHandle(TextureImage::ThreadShared, (void*)mTextureInfo.mTexture, GLContext::TextureID);
|
||||
|
||||
// We want forget about this now, so delete the texture. Assigning it to zero
|
||||
// ensures that we create a new one in Lock()
|
||||
sPluginContext->fDeleteTextures(1, &mTextureInfo.mTexture);
|
||||
mTextureInfo.mTexture = 0;
|
||||
|
||||
return mCurrentHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
TextureInfo mTextureInfo;
|
||||
SharedTextureHandle mCurrentHandle;
|
||||
|
||||
bool mNeedNewImage;
|
||||
|
||||
Mutex mLock;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
@ -169,12 +78,12 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
||||
:
|
||||
mDrawingModel(kDefaultDrawingModel),
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mSurface(nsnull),
|
||||
mANPDrawingModel(0),
|
||||
mOnScreen(true),
|
||||
mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary),
|
||||
mWakeLocked(false),
|
||||
mFullScreen(false),
|
||||
mInverted(false),
|
||||
#endif
|
||||
mRunning(NOT_STARTED),
|
||||
mWindowless(false),
|
||||
@ -209,6 +118,10 @@ nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
|
||||
PR_Free((void *)mMIMEType);
|
||||
mMIMEType = nsnull;
|
||||
}
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
SetWakeLock(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -216,18 +129,6 @@ nsNPAPIPluginInstance::Destroy()
|
||||
{
|
||||
Stop();
|
||||
mPlugin = nsnull;
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
mContentTexture = nsnull;
|
||||
mContentSurface = nsnull;
|
||||
|
||||
std::map<void*, VideoInfo*>::iterator it;
|
||||
for (it = mVideos.begin(); it != mVideos.end(); it++) {
|
||||
delete it->second;
|
||||
}
|
||||
mVideos.clear();
|
||||
SetWakeLock(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
@ -871,24 +772,6 @@ void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
|
||||
}
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::NotifySize(nsIntSize size)
|
||||
{
|
||||
if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() ||
|
||||
size == mCurrentSize)
|
||||
return;
|
||||
|
||||
mCurrentSize = size;
|
||||
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kDraw_ANPEventType;
|
||||
event.data.draw.model = kOpenGL_ANPDrawingModel;
|
||||
event.data.draw.data.surfaceSize.width = size.width;
|
||||
event.data.draw.data.surfaceSize.height = size.height;
|
||||
|
||||
HandleEvent(&event, nsnull);
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::SetANPDrawingModel(PRUint32 aModel)
|
||||
{
|
||||
mANPDrawingModel = aModel;
|
||||
@ -949,122 +832,6 @@ void nsNPAPIPluginInstance::SetWakeLock(bool aLocked)
|
||||
hal::WAKE_LOCK_NO_CHANGE);
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::EnsureSharedTexture()
|
||||
{
|
||||
if (!mContentTexture)
|
||||
mContentTexture = new SharedPluginTexture();
|
||||
}
|
||||
|
||||
GLContext* nsNPAPIPluginInstance::GLContext()
|
||||
{
|
||||
if (!EnsureGLContext())
|
||||
return nsnull;
|
||||
|
||||
return sPluginContext;
|
||||
}
|
||||
|
||||
TextureInfo nsNPAPIPluginInstance::LockContentTexture()
|
||||
{
|
||||
EnsureSharedTexture();
|
||||
return mContentTexture->Lock();
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::ReleaseContentTexture(TextureInfo& aTextureInfo)
|
||||
{
|
||||
EnsureSharedTexture();
|
||||
mContentTexture->Release(aTextureInfo);
|
||||
}
|
||||
|
||||
nsSurfaceTexture* nsNPAPIPluginInstance::CreateSurfaceTexture()
|
||||
{
|
||||
if (!EnsureGLContext())
|
||||
return nsnull;
|
||||
|
||||
GLuint texture = TexturePoolOGL::AcquireTexture();
|
||||
if (!texture)
|
||||
return nsnull;
|
||||
|
||||
nsSurfaceTexture* surface = nsSurfaceTexture::Create(texture);
|
||||
if (!surface)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIRunnable> frameCallback = NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::RedrawPlugin);
|
||||
surface->SetFrameAvailableCallback(frameCallback);
|
||||
return surface;
|
||||
}
|
||||
|
||||
void* nsNPAPIPluginInstance::AcquireContentWindow()
|
||||
{
|
||||
if (!mContentSurface) {
|
||||
mContentSurface = CreateSurfaceTexture();
|
||||
|
||||
if (!mContentSurface)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return mContentSurface->GetNativeWindow();
|
||||
}
|
||||
|
||||
SharedTextureHandle nsNPAPIPluginInstance::CreateSharedHandle()
|
||||
{
|
||||
if (mContentTexture) {
|
||||
return mContentTexture->CreateSharedHandle();
|
||||
} else if (mContentSurface) {
|
||||
EnsureGLContext();
|
||||
return sPluginContext->CreateSharedHandle(TextureImage::ThreadShared, mContentSurface, GLContext::SurfaceTexture);
|
||||
} else return nsnull;
|
||||
}
|
||||
|
||||
void* nsNPAPIPluginInstance::AcquireVideoWindow()
|
||||
{
|
||||
nsSurfaceTexture* surface = CreateSurfaceTexture();
|
||||
if (!surface)
|
||||
return nsnull;
|
||||
|
||||
VideoInfo* info = new VideoInfo(surface);
|
||||
|
||||
void* window = info->mSurfaceTexture->GetNativeWindow();
|
||||
mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::ReleaseVideoWindow(void* window)
|
||||
{
|
||||
std::map<void*, VideoInfo*>::iterator it = mVideos.find(window);
|
||||
if (it == mVideos.end())
|
||||
return;
|
||||
|
||||
delete it->second;
|
||||
mVideos.erase(window);
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::SetVideoDimensions(void* window, gfxRect aDimensions)
|
||||
{
|
||||
std::map<void*, VideoInfo*>::iterator it;
|
||||
|
||||
it = mVideos.find(window);
|
||||
if (it == mVideos.end())
|
||||
return;
|
||||
|
||||
it->second->mDimensions = aDimensions;
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::GetVideos(nsTArray<VideoInfo*>& aVideos)
|
||||
{
|
||||
std::map<void*, VideoInfo*>::iterator it;
|
||||
for (it = mVideos.begin(); it != mVideos.end(); it++)
|
||||
aVideos.AppendElement(it->second);
|
||||
}
|
||||
|
||||
void nsNPAPIPluginInstance::SetInverted(bool aInverted)
|
||||
{
|
||||
if (aInverted == mInverted)
|
||||
return;
|
||||
|
||||
mInverted = aInverted;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
|
||||
|
@ -16,13 +16,8 @@
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "GLContext.h"
|
||||
#include "nsSurfaceTexture.h"
|
||||
#include <map>
|
||||
class PluginEventRunnable;
|
||||
class SharedPluginTexture;
|
||||
#endif
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
@ -129,7 +124,6 @@ public:
|
||||
void NotifyOnScreen(bool aOnScreen);
|
||||
void MemoryPressure();
|
||||
void NotifyFullScreen(bool aFullScreen);
|
||||
void NotifySize(nsIntSize size);
|
||||
|
||||
bool IsOnScreen() {
|
||||
return mOnScreen;
|
||||
@ -148,61 +142,6 @@ public:
|
||||
void SetFullScreenOrientation(PRUint32 orientation);
|
||||
|
||||
void SetWakeLock(bool aLock);
|
||||
|
||||
mozilla::gl::GLContext* GLContext();
|
||||
|
||||
// For ANPOpenGL
|
||||
class TextureInfo {
|
||||
public:
|
||||
TextureInfo() :
|
||||
mTexture(0), mWidth(0), mHeight(0), mInternalFormat(0)
|
||||
{
|
||||
}
|
||||
|
||||
TextureInfo(GLuint aTexture, PRInt32 aWidth, PRInt32 aHeight, GLuint aInternalFormat) :
|
||||
mTexture(aTexture), mWidth(aWidth), mHeight(aHeight), mInternalFormat(aInternalFormat)
|
||||
{
|
||||
}
|
||||
|
||||
GLuint mTexture;
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
GLuint mInternalFormat;
|
||||
};
|
||||
|
||||
TextureInfo LockContentTexture();
|
||||
void ReleaseContentTexture(TextureInfo& aTextureInfo);
|
||||
|
||||
// For ANPNativeWindow
|
||||
void* AcquireContentWindow();
|
||||
|
||||
mozilla::gl::SharedTextureHandle CreateSharedHandle();
|
||||
|
||||
// For ANPVideo
|
||||
class VideoInfo {
|
||||
public:
|
||||
VideoInfo(nsSurfaceTexture* aSurfaceTexture) :
|
||||
mSurfaceTexture(aSurfaceTexture)
|
||||
{
|
||||
}
|
||||
|
||||
~VideoInfo()
|
||||
{
|
||||
mSurfaceTexture = nsnull;
|
||||
}
|
||||
|
||||
nsRefPtr<nsSurfaceTexture> mSurfaceTexture;
|
||||
gfxRect mDimensions;
|
||||
};
|
||||
|
||||
void* AcquireVideoWindow();
|
||||
void ReleaseVideoWindow(void* aWindow);
|
||||
void SetVideoDimensions(void* aWindow, gfxRect aDimensions);
|
||||
|
||||
void GetVideos(nsTArray<VideoInfo*>& aVideos);
|
||||
|
||||
void SetInverted(bool aInverted);
|
||||
bool Inverted() { return mInverted; }
|
||||
#endif
|
||||
|
||||
nsresult NewStreamListener(const char* aURL, void* notifyData,
|
||||
@ -281,6 +220,7 @@ protected:
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
PRUint32 mANPDrawingModel;
|
||||
nsCOMPtr<nsIRunnable> mSurfaceGetter;
|
||||
|
||||
friend class PluginEventRunnable;
|
||||
|
||||
@ -290,10 +230,6 @@ protected:
|
||||
PRUint32 mFullScreenOrientation;
|
||||
bool mWakeLocked;
|
||||
bool mFullScreen;
|
||||
bool mInverted;
|
||||
|
||||
nsRefPtr<SharedPluginTexture> mContentTexture;
|
||||
nsRefPtr<nsSurfaceTexture> mContentSurface;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
@ -342,13 +278,8 @@ private:
|
||||
|
||||
bool mUsePluginLayersPref;
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
void EnsureSharedTexture();
|
||||
nsSurfaceTexture* CreateSurfaceTexture();
|
||||
|
||||
std::map<void*, VideoInfo*> mVideos;
|
||||
void* mSurface;
|
||||
bool mOnScreen;
|
||||
|
||||
nsIntSize mCurrentSize;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,6 @@ using mozilla::DefaultXDisplay;
|
||||
#include "nsSize.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "SharedTextureImage.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsObjectFrame.h"
|
||||
#include "nsIPluginDocument.h"
|
||||
@ -85,6 +84,7 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "ANPBase.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidMediaLayer.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
static nsPluginInstanceOwner* sFullScreenInstance = nsnull;
|
||||
@ -170,38 +170,6 @@ static void OnDestroyImage(void* aPluginInstanceOwner)
|
||||
already_AddRefed<ImageContainer>
|
||||
nsPluginInstanceOwner::GetImageContainer()
|
||||
{
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
// Right now we only draw with Gecko layers on Honeycomb and higher. See Paint()
|
||||
// for what we do on other versions.
|
||||
if (AndroidBridge::Bridge()->GetAPIVersion() < 11)
|
||||
return NULL;
|
||||
|
||||
nsRefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
|
||||
|
||||
Image::Format format = Image::SHARED_TEXTURE;
|
||||
nsRefPtr<Image> img = container->CreateImage(&format, 1);
|
||||
|
||||
SharedTextureImage::Data data;
|
||||
data.mHandle = mInstance->CreateSharedHandle();
|
||||
data.mShareType = mozilla::gl::TextureImage::ThreadShared;
|
||||
data.mInverted = mInstance->Inverted();
|
||||
|
||||
gfxRect r = GetPluginRect();
|
||||
data.mSize = gfxIntSize(r.width, r.height);
|
||||
|
||||
SharedTextureImage* pluginImage = static_cast<SharedTextureImage*>(img.get());
|
||||
pluginImage->SetData(data);
|
||||
|
||||
container->SetCurrentImage(img);
|
||||
|
||||
float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
|
||||
float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
|
||||
r.Scale(xResolution, yResolution);
|
||||
mInstance->NotifySize(nsIntSize(r.width, r.height));
|
||||
|
||||
return container.forget();
|
||||
#endif
|
||||
|
||||
if (mInstance) {
|
||||
nsRefPtr<ImageContainer> container;
|
||||
// Every call to nsIPluginInstance::GetImage() creates
|
||||
@ -338,7 +306,9 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||
mWaitingForPaint = false;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mInverted = false;
|
||||
mFullScreen = false;
|
||||
mLayer = nsnull;
|
||||
mJavaView = nsnull;
|
||||
#endif
|
||||
}
|
||||
@ -1754,6 +1724,26 @@ gfxRect nsPluginInstanceOwner::GetPluginRect()
|
||||
return gfxRect(intBounds);
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::SendSize(int width, int height)
|
||||
{
|
||||
if (!mInstance)
|
||||
return;
|
||||
|
||||
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||
|
||||
if (model != kOpenGL_ANPDrawingModel)
|
||||
return;
|
||||
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kDraw_ANPEventType;
|
||||
event.data.draw.model = kOpenGL_ANPDrawingModel;
|
||||
event.data.draw.data.surfaceSize.width = width;
|
||||
event.data.draw.data.surfaceSize.height = height;
|
||||
|
||||
mInstance->HandleEvent(&event, nsnull);
|
||||
}
|
||||
|
||||
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect /* = gfxRect(0, 0, 0, 0) */)
|
||||
{
|
||||
if (!mJavaView) {
|
||||
@ -1789,46 +1779,6 @@ void nsPluginInstanceOwner::RemovePluginView()
|
||||
sFullScreenInstance = nsnull;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
|
||||
{
|
||||
if (!mInstance)
|
||||
return;
|
||||
|
||||
mInstance->GetVideos(aVideos);
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer> nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
|
||||
{
|
||||
nsRefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
|
||||
|
||||
Image::Format format = Image::SHARED_TEXTURE;
|
||||
nsRefPtr<Image> img = container->CreateImage(&format, 1);
|
||||
|
||||
SharedTextureImage::Data data;
|
||||
|
||||
data.mHandle = mInstance->GLContext()->CreateSharedHandle(gl::TextureImage::ThreadShared, aVideoInfo->mSurfaceTexture, gl::GLContext::SurfaceTexture);
|
||||
data.mShareType = mozilla::gl::TextureImage::ThreadShared;
|
||||
data.mInverted = mInstance->Inverted();
|
||||
data.mSize = gfxIntSize(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height);
|
||||
|
||||
SharedTextureImage* pluginImage = static_cast<SharedTextureImage*>(img.get());
|
||||
pluginImage->SetData(data);
|
||||
container->SetCurrentImage(img);
|
||||
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
nsIntRect nsPluginInstanceOwner::GetVisibleRect()
|
||||
{
|
||||
gfxRect r = nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height);
|
||||
|
||||
float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
|
||||
float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
|
||||
r.Scale(xResolution, yResolution);
|
||||
|
||||
return nsIntRect(r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::Invalidate() {
|
||||
NPRect rect;
|
||||
rect.left = rect.top = 0;
|
||||
@ -2806,6 +2756,10 @@ nsPluginInstanceOwner::Destroy()
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
RemovePluginView();
|
||||
|
||||
if (mLayer)
|
||||
mLayer->SetVisible(false);
|
||||
|
||||
#endif
|
||||
|
||||
if (mWidget) {
|
||||
@ -2921,13 +2875,29 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||
|
||||
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||
|
||||
gfxRect pluginRect = GetPluginRect();
|
||||
|
||||
if (model == kSurface_ANPDrawingModel) {
|
||||
if (!AddPluginView(GetPluginRect())) {
|
||||
if (!AddPluginView(pluginRect)) {
|
||||
Invalidate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (model == kOpenGL_ANPDrawingModel) {
|
||||
if (!mLayer)
|
||||
mLayer = new AndroidMediaLayer();
|
||||
|
||||
mLayer->UpdatePosition(pluginRect);
|
||||
|
||||
float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
|
||||
float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
|
||||
pluginRect.Scale(xResolution, yResolution);
|
||||
|
||||
SendSize((int)pluginRect.width, (int)pluginRect.height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (model != kBitmap_ANPDrawingModel)
|
||||
return;
|
||||
|
||||
@ -3664,6 +3634,9 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (mInstance) {
|
||||
if (mLayer)
|
||||
mLayer->SetVisible(mPluginDocumentActiveState);
|
||||
|
||||
if (!mPluginDocumentActiveState)
|
||||
RemovePluginView();
|
||||
|
||||
|
@ -51,6 +51,12 @@ class gfxXlibSurface;
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
namespace mozilla {
|
||||
class AndroidMediaLayer;
|
||||
}
|
||||
#endif
|
||||
|
||||
// X.h defines KeyPress
|
||||
#ifdef KeyPress
|
||||
#undef KeyPress
|
||||
@ -254,11 +260,21 @@ public:
|
||||
bool UseAsyncRendering();
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// Returns the image container for the specified VideoInfo
|
||||
void GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos);
|
||||
already_AddRefed<ImageContainer> GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo);
|
||||
nsIntRect GetVisibleRect() {
|
||||
return nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height);
|
||||
}
|
||||
|
||||
nsIntRect GetVisibleRect();
|
||||
void SetInverted(bool aInverted) {
|
||||
mInverted = aInverted;
|
||||
}
|
||||
|
||||
bool Inverted() {
|
||||
return mInverted;
|
||||
}
|
||||
|
||||
mozilla::AndroidMediaLayer* Layer() {
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
void Invalidate();
|
||||
|
||||
@ -281,12 +297,19 @@ private:
|
||||
|
||||
void FixUpURLS(const nsString &name, nsAString &value);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
void SendSize(int width, int height);
|
||||
|
||||
gfxRect GetPluginRect();
|
||||
bool AddPluginView(const gfxRect& aRect = gfxRect(0, 0, 0, 0));
|
||||
void RemovePluginView();
|
||||
|
||||
bool mInverted;
|
||||
bool mFullScreen;
|
||||
|
||||
void* mJavaView;
|
||||
|
||||
// For kOpenGL_ANPDrawingModel
|
||||
nsRefPtr<mozilla::AndroidMediaLayer> mLayer;
|
||||
#endif
|
||||
|
||||
nsPluginNativeWindow *mPluginWindow;
|
||||
|
@ -1848,16 +1848,4 @@ public class GeckoAppShell
|
||||
public static String getGfxInfoData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerSurfaceTextureFrameListener(SurfaceTexture surfaceTexture, final int id) {
|
||||
surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
|
||||
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
|
||||
GeckoAppShell.onSurfaceTextureFrameAvailable(surfaceTexture, id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void unregisterSurfaceTextureFrameListener(SurfaceTexture surfaceTexture) {
|
||||
surfaceTexture.setOnFrameAvailableListener(null);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "prlink.h"
|
||||
|
||||
@ -52,7 +51,6 @@ typedef uintptr_t SharedTextureHandle;
|
||||
|
||||
enum ShaderProgramType {
|
||||
RGBALayerProgramType,
|
||||
RGBALayerExternalProgramType,
|
||||
BGRALayerProgramType,
|
||||
RGBXLayerProgramType,
|
||||
BGRXLayerProgramType,
|
||||
@ -858,26 +856,10 @@ public:
|
||||
return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
|
||||
}
|
||||
|
||||
enum SharedTextureBufferType {
|
||||
TextureID
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
, SurfaceTexture
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new shared GLContext content handle, must be released by ReleaseSharedHandle.
|
||||
*/
|
||||
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType) { return nsnull; }
|
||||
/**
|
||||
* Create a new shared GLContext content handle, using the passed buffer as a source.
|
||||
* Must be released by ReleaseSharedHandle. UpdateSharedHandle will have no effect
|
||||
* on handles created with this method, as it is the caller owns the source (the passed buffer)
|
||||
* and is responsible for updating it accordingly.
|
||||
*/
|
||||
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType,
|
||||
void* aBuffer,
|
||||
SharedTextureBufferType aBufferType) { return nsnull; }
|
||||
/**
|
||||
* Publish GLContext content to intermediate buffer attached to shared handle.
|
||||
* Shared handle content is ready to be used after call returns, and no need extra Flush/Finish are required.
|
||||
@ -900,28 +882,12 @@ public:
|
||||
*/
|
||||
virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle) { }
|
||||
|
||||
|
||||
typedef struct {
|
||||
GLenum mTarget;
|
||||
ShaderProgramType mProgramType;
|
||||
gfx3DMatrix mTextureTransform;
|
||||
} SharedHandleDetails;
|
||||
|
||||
/**
|
||||
* Returns information necessary for rendering a shared handle.
|
||||
* These values change depending on what sharing mechanism is in use
|
||||
*/
|
||||
virtual bool GetSharedHandleDetails(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle,
|
||||
SharedHandleDetails& aDetails) { return false; }
|
||||
/**
|
||||
* Attach Shared GL Handle to GL_TEXTURE_2D target
|
||||
* GLContext must be current before this call
|
||||
*/
|
||||
virtual bool AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle) { return false; }
|
||||
|
||||
/**
|
||||
* Detach Shared GL Handle from GL_TEXTURE_2D target
|
||||
*/
|
||||
|
@ -32,7 +32,6 @@
|
||||
/* from widget */
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "AndroidBridge.h"
|
||||
#include "nsSurfaceTexture.h"
|
||||
#endif
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
|
||||
@ -120,7 +119,6 @@ public:
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
|
||||
#if defined(MOZ_PLATFORM_MAEMO) || defined(MOZ_WIDGET_GONK)
|
||||
static bool gUseBackingSurface = true;
|
||||
#else
|
||||
@ -627,16 +625,10 @@ public:
|
||||
}
|
||||
|
||||
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType);
|
||||
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType,
|
||||
void* aBuffer,
|
||||
SharedTextureBufferType aBufferType);
|
||||
virtual void UpdateSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
virtual bool GetSharedHandleDetails(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle,
|
||||
SharedHandleDetails& aDetails);
|
||||
virtual bool AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
protected:
|
||||
@ -698,61 +690,14 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
Image
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
, SurfaceTexture
|
||||
#endif
|
||||
} SharedHandleType;
|
||||
|
||||
class SharedTextureHandleWrapper
|
||||
class EGLTextureWrapper
|
||||
{
|
||||
public:
|
||||
SharedTextureHandleWrapper(SharedHandleType aHandleType) : mHandleType(aHandleType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SharedTextureHandleWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
SharedHandleType Type() { return mHandleType; }
|
||||
|
||||
SharedHandleType mHandleType;
|
||||
};
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class SurfaceTextureWrapper: public SharedTextureHandleWrapper
|
||||
{
|
||||
public:
|
||||
SurfaceTextureWrapper(nsSurfaceTexture* aSurfaceTexture) :
|
||||
SharedTextureHandleWrapper(SharedHandleType::SurfaceTexture)
|
||||
, mSurfaceTexture(aSurfaceTexture)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SurfaceTextureWrapper() {
|
||||
mSurfaceTexture = nsnull;
|
||||
}
|
||||
|
||||
nsSurfaceTexture* SurfaceTexture() { return mSurfaceTexture; }
|
||||
|
||||
nsRefPtr<nsSurfaceTexture> mSurfaceTexture;
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
class EGLTextureWrapper : public SharedTextureHandleWrapper
|
||||
{
|
||||
public:
|
||||
EGLTextureWrapper(GLContext* aContext, GLuint aTexture, bool aOwnsTexture) :
|
||||
SharedTextureHandleWrapper(SharedHandleType::Image)
|
||||
, mContext(aContext)
|
||||
EGLTextureWrapper(GLContext* aContext, GLuint aTexture)
|
||||
: mContext(aContext)
|
||||
, mTexture(aTexture)
|
||||
, mEGLImage(nsnull)
|
||||
, mSyncObject(nsnull)
|
||||
, mOwnsTexture(aOwnsTexture)
|
||||
{
|
||||
}
|
||||
|
||||
@ -827,16 +772,11 @@ public:
|
||||
return result == LOCAL_EGL_CONDITION_SATISFIED;
|
||||
}
|
||||
|
||||
bool OwnsTexture() {
|
||||
return mOwnsTexture;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GLContext> mContext;
|
||||
GLuint mTexture;
|
||||
EGLImage mEGLImage;
|
||||
EGLSync mSyncObject;
|
||||
bool mOwnsTexture;
|
||||
};
|
||||
|
||||
void
|
||||
@ -848,12 +788,9 @@ GLContextEGL::UpdateSharedHandle(TextureImage::TextureShareType aType,
|
||||
return;
|
||||
}
|
||||
|
||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(aSharedHandle);
|
||||
|
||||
NS_ASSERTION(wrapper->Type() == SharedHandleType::Image, "Expected EGLImage shared handle");
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = reinterpret_cast<EGLTextureWrapper*>(wrapper);
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
// We need to copy the current GLContext drawing buffer to the texture
|
||||
// exported by the EGLImage. Need to save both the read FBO and the texture
|
||||
// binding, because we're going to munge them to do this.
|
||||
@ -893,56 +830,19 @@ GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType)
|
||||
CreateTextureForOffscreen(ChooseGLFormats(fmt, GLContext::ForceRGBA), mOffscreenSize, texture);
|
||||
// texture ownership moved to EGLTextureWrapper after this point
|
||||
// and texture will be deleted in EGLTextureWrapper dtor
|
||||
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture, true);
|
||||
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture);
|
||||
if (!tex->CreateEGLImage()) {
|
||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||
ReleaseSharedHandle(aType, (SharedTextureHandle)tex);
|
||||
|
||||
// Stop trying to create shared image Handle
|
||||
mShareWithEGLImage = false;
|
||||
return nsnull;
|
||||
}
|
||||
// Raw pointer shared across threads
|
||||
return (SharedTextureHandle)tex;
|
||||
}
|
||||
|
||||
SharedTextureHandle
|
||||
GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType,
|
||||
void* aBuffer,
|
||||
SharedTextureBufferType aBufferType)
|
||||
{
|
||||
// Both EGLImage and SurfaceTexture only support ThreadShared currently, but
|
||||
// it's possible to make SurfaceTexture work across processes. We should do that.
|
||||
if (aType != TextureImage::ThreadShared)
|
||||
return nsnull;
|
||||
|
||||
switch (aBufferType) {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SharedTextureBufferType::SurfaceTexture:
|
||||
if (!IsExtensionSupported(GLContext::OES_EGL_image_external)) {
|
||||
NS_WARNING("Missing GL_OES_EGL_image_external");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast<nsSurfaceTexture*>(aBuffer));
|
||||
#endif
|
||||
case SharedTextureBufferType::TextureID: {
|
||||
if (!mShareWithEGLImage)
|
||||
return nsnull;
|
||||
|
||||
GLuint texture = (GLuint)aBuffer;
|
||||
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture, false);
|
||||
if (!tex->CreateEGLImage()) {
|
||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||
delete tex;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return (SharedTextureHandle)tex;
|
||||
}
|
||||
default:
|
||||
NS_ERROR("Unknown shared texture buffer type");
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void GLContextEGL::ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle)
|
||||
{
|
||||
@ -951,72 +851,22 @@ void GLContextEGL::ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
return;
|
||||
}
|
||||
|
||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(aSharedHandle);
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
switch (wrapper->Type()) {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SharedHandleType::SurfaceTexture:
|
||||
delete wrapper;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SharedHandleType::Image: {
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
GLContext *ctx = wrap->GetContext();
|
||||
if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
|
||||
ctx = ctx->GetSharedContext();
|
||||
}
|
||||
// If we have a context, then we need to delete the texture;
|
||||
// if we don't have a context (either real or shared),
|
||||
// then they went away when the contex was deleted, because it
|
||||
// was the only one that had access to it.
|
||||
if (wrap->OwnsTexture() && ctx && !ctx->IsDestroyed() && ctx->MakeCurrent()) {
|
||||
GLuint texture = wrap->GetTextureID();
|
||||
ctx->fDeleteTextures(1, &texture);
|
||||
}
|
||||
delete wrap;
|
||||
break;
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
GLContext *ctx = wrap->GetContext();
|
||||
if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
|
||||
ctx = ctx->GetSharedContext();
|
||||
}
|
||||
|
||||
default:
|
||||
NS_ERROR("Unknown shared handle type");
|
||||
// If we have a context, then we need to delete the texture;
|
||||
// if we don't have a context (either real or shared),
|
||||
// then they went away when the contex was deleted, because it
|
||||
// was the only one that had access to it.
|
||||
if (ctx && !ctx->IsDestroyed() && ctx->MakeCurrent()) {
|
||||
GLuint texture = wrap->GetTextureID();
|
||||
ctx->fDeleteTextures(1, &texture);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLContextEGL::GetSharedHandleDetails(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle,
|
||||
SharedHandleDetails& aDetails)
|
||||
{
|
||||
if (aType != TextureImage::ThreadShared)
|
||||
return false;
|
||||
|
||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(aSharedHandle);
|
||||
|
||||
switch (wrapper->Type()) {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SharedHandleType::SurfaceTexture: {
|
||||
SurfaceTextureWrapper* surfaceWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
||||
|
||||
aDetails.mTarget = LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
aDetails.mProgramType = RGBALayerExternalProgramType;
|
||||
surfaceWrapper->SurfaceTexture()->GetTransformMatrix(aDetails.mTextureTransform);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case SharedHandleType::Image:
|
||||
aDetails.mTarget = LOCAL_GL_TEXTURE_2D;
|
||||
aDetails.mProgramType = RGBALayerProgramType;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("Unknown shared handle type");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
delete wrap;
|
||||
}
|
||||
|
||||
bool GLContextEGL::AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
@ -1025,41 +875,11 @@ bool GLContextEGL::AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
if (aType != TextureImage::ThreadShared)
|
||||
return false;
|
||||
|
||||
SharedTextureHandleWrapper* wrapper = reinterpret_cast<SharedTextureHandleWrapper*>(aSharedHandle);
|
||||
|
||||
switch (wrapper->Type()) {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SharedHandleType::SurfaceTexture: {
|
||||
#ifndef DEBUG
|
||||
/**
|
||||
* NOTE: SurfaceTexture spams us if there are any existing GL errors, so we'll clear
|
||||
* them here in order to avoid that.
|
||||
*/
|
||||
GetAndClearError();
|
||||
#endif
|
||||
SurfaceTextureWrapper* surfaceTextureWrapper = reinterpret_cast<SurfaceTextureWrapper*>(wrapper);
|
||||
|
||||
// FIXME: SurfaceTexture provides a transform matrix which is supposed to
|
||||
// be applied to the texture coordinates. We should return that here
|
||||
// so we can render correctly. Bug 775083
|
||||
surfaceTextureWrapper->SurfaceTexture()->UpdateTexImage();
|
||||
break;
|
||||
}
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
case SharedHandleType::Image: {
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_ERROR("Unknown shared handle type");
|
||||
return false;
|
||||
}
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
wrap->WaitSync();
|
||||
fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3252,7 +3252,6 @@ typedef void* GLeglImage;
|
||||
#define LOCAL_EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
#define LOCAL_EGL_READ 0x305A
|
||||
#define LOCAL_EGL_DRAW 0x3059
|
||||
#define LOCAL_EGL_BAD_PARAMETER 0x300C
|
||||
#define LOCAL_EGL_CONTEXT_LOST 0x300E
|
||||
|
||||
// EGL_KHR_image_base (not supplied by EGL_KHR_image!)
|
||||
@ -3264,9 +3263,6 @@ typedef void* GLeglImage;
|
||||
// EGL_KHR_gl_texture_2D_image
|
||||
#define LOCAL_EGL_GL_TEXTURE_2D 0x30B1
|
||||
|
||||
// OES_EGL_image_external
|
||||
#define LOCAL_GL_TEXTURE_EXTERNAL 0x8D65
|
||||
|
||||
// EGL_KHR_fence_sync
|
||||
#define LOCAL_EGL_SYNC_FENCE 0x30F9
|
||||
#define LOCAL_EGL_SYNC_TYPE 0x30F7
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/ipc/CrossProcessMutex.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "SharedTextureImage.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "yuv_convert.h"
|
||||
@ -44,8 +43,6 @@ ImageFactory::CreateImage(const Image::Format *aFormats,
|
||||
img = new PlanarYCbCrImage(aRecycleBin);
|
||||
} else if (FormatInList(aFormats, aNumFormats, Image::CAIRO_SURFACE)) {
|
||||
img = new CairoImage();
|
||||
} else if (FormatInList(aFormats, aNumFormats, Image::SHARED_TEXTURE)) {
|
||||
img = new SharedTextureImage();
|
||||
#ifdef XP_MACOSX
|
||||
} else if (FormatInList(aFormats, aNumFormats, Image::MAC_IO_SURFACE)) {
|
||||
img = new MacIOSurfaceImage();
|
||||
|
@ -122,11 +122,6 @@ public:
|
||||
*/
|
||||
REMOTE_IMAGE_BITMAP,
|
||||
|
||||
/**
|
||||
* A OpenGL texture that can be shared across threads or processes
|
||||
*/
|
||||
SHARED_TEXTURE,
|
||||
|
||||
/**
|
||||
* An DXGI shared surface handle that can be shared with a remote process.
|
||||
*/
|
||||
|
@ -39,8 +39,6 @@ EXPORTS = \
|
||||
LayerManagerOGLProgram.h \
|
||||
ReadbackLayer.h \
|
||||
LayerSorter.h \
|
||||
TexturePoolOGL.h \
|
||||
SharedTextureImage.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
@ -69,7 +67,6 @@ CPPSRCS = \
|
||||
LayerManagerOGLProgram.cpp \
|
||||
LayerSorter.cpp \
|
||||
ImageLayers.cpp \
|
||||
TexturePoolOGL.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
|
@ -1,44 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_SHAREDTEXTUREIMAGE_H
|
||||
#define GFX_SHAREDTEXTUREIMAGE_H
|
||||
|
||||
#include "ImageLayers.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
// Split into a separate header from ImageLayers.h due to GLContext.h dependence
|
||||
// Implementation remains in ImageLayers.cpp
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API SharedTextureImage : public Image {
|
||||
public:
|
||||
struct Data {
|
||||
gl::SharedTextureHandle mHandle;
|
||||
gl::TextureImage::TextureShareType mShareType;
|
||||
gfxIntSize mSize;
|
||||
bool mInverted;
|
||||
};
|
||||
|
||||
void SetData(const Data& aData) { mData = aData; }
|
||||
const Data* GetData() { return &mData; }
|
||||
|
||||
gfxIntSize GetSize() { return mData.mSize; }
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return NULL; }
|
||||
|
||||
SharedTextureImage() : Image(NULL, SHARED_TEXTURE) {}
|
||||
|
||||
private:
|
||||
Data mData;
|
||||
};
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
||||
|
||||
#endif // GFX_SHAREDTEXTUREIMAGE_H
|
@ -387,7 +387,7 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
if (!handle) {
|
||||
handle = mGLContext->CreateSharedHandle(flags);
|
||||
if (handle) {
|
||||
mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size(), false);
|
||||
mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size());
|
||||
}
|
||||
}
|
||||
if (handle) {
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "mozilla/layers/PLayersParent.h"
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "SharedTextureImage.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "mozilla/layers/ImageContainerChild.h"
|
||||
@ -278,17 +277,6 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
->Paint(aContext, nsnull);
|
||||
}
|
||||
|
||||
if (image->GetFormat() == Image::SHARED_TEXTURE &&
|
||||
BasicManager()->GetParentBackendType() == mozilla::layers::LAYERS_OPENGL) {
|
||||
SharedTextureImage *sharedImage = static_cast<SharedTextureImage*>(image);
|
||||
const SharedTextureImage::Data *data = sharedImage->GetData();
|
||||
|
||||
SharedTextureDescriptor texture(data->mShareType, data->mHandle, data->mSize, data->mInverted);
|
||||
SurfaceDescriptor descriptor(texture);
|
||||
BasicManager()->PaintedImage(BasicManager()->Hold(this), descriptor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (image->GetFormat() == Image::PLANAR_YCBCR && BasicManager()->IsCompositingCheap()) {
|
||||
PlanarYCbCrImage *YCbCrImage = static_cast<PlanarYCbCrImage*>(image);
|
||||
const PlanarYCbCrImage::Data *data = YCbCrImage->GetData();
|
||||
|
@ -40,7 +40,6 @@ struct SharedTextureDescriptor {
|
||||
TextureShareType shareType;
|
||||
SharedTextureHandle handle;
|
||||
nsIntSize size;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorGralloc {
|
||||
|
@ -335,7 +335,7 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
||||
if (IsValidSharedTexDescriptor(aNewFront)) {
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
if (!IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||
mFrontBufferDescriptor = SharedTextureDescriptor(TextureImage::ThreadShared, 0, nsIntSize(0, 0), false);
|
||||
mFrontBufferDescriptor = SharedTextureDescriptor(TextureImage::ThreadShared, 0, nsIntSize(0, 0));
|
||||
}
|
||||
*aNewBack = mFrontBufferDescriptor;
|
||||
mFrontBufferDescriptor = aNewFront;
|
||||
|
@ -18,32 +18,12 @@
|
||||
# include "mozilla/X11Util.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "nsSurfaceTexture.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static void
|
||||
MakeTextureIfNeeded(GLContext* gl, GLuint& aTexture)
|
||||
{
|
||||
if (aTexture != 0)
|
||||
return;
|
||||
|
||||
gl->fGenTextures(1, &aTexture);
|
||||
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
|
||||
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an event used to unref a GLContext on the main thread and
|
||||
* optionally delete a texture associated with that context.
|
||||
@ -696,9 +676,6 @@ ImageLayerOGL::LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize)
|
||||
ShadowImageLayerOGL::ShadowImageLayerOGL(LayerManagerOGL* aManager)
|
||||
: ShadowImageLayer(aManager, nsnull)
|
||||
, LayerOGL(aManager)
|
||||
, mSharedHandle(0)
|
||||
, mInverted(false)
|
||||
, mTexture(0)
|
||||
{
|
||||
mImplData = static_cast<LayerOGL*>(this);
|
||||
}
|
||||
@ -710,23 +687,15 @@ bool
|
||||
ShadowImageLayerOGL::Init(const SharedImage& aFront)
|
||||
{
|
||||
if (aFront.type() == SharedImage::TSurfaceDescriptor) {
|
||||
SurfaceDescriptor surface = aFront.get_SurfaceDescriptor();
|
||||
if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
|
||||
SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor();
|
||||
mSize = texture.size();
|
||||
mSharedHandle = texture.handle();
|
||||
mShareType = texture.shareType();
|
||||
mInverted = texture.inverted();
|
||||
} else {
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, surface);
|
||||
mSize = autoSurf.Size();
|
||||
mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height),
|
||||
autoSurf.ContentType(),
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
mForceSingleTile
|
||||
? TextureImage::ForceSingleTile
|
||||
: TextureImage::NoFlags);
|
||||
}
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, aFront.get_SurfaceDescriptor());
|
||||
mSize = autoSurf.Size();
|
||||
mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height),
|
||||
autoSurf.ContentType(),
|
||||
LOCAL_GL_CLAMP_TO_EDGE,
|
||||
mForceSingleTile
|
||||
? TextureImage::ForceSingleTile
|
||||
: TextureImage::NoFlags);
|
||||
return true;
|
||||
} else {
|
||||
YUVImage yuv = aFront.get_YUVImage();
|
||||
|
||||
@ -770,31 +739,15 @@ ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
|
||||
mImageVersion = 0;
|
||||
}
|
||||
} else if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
|
||||
SurfaceDescriptor surface = aNewFront.get_SurfaceDescriptor();
|
||||
|
||||
if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
|
||||
SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor();
|
||||
|
||||
SharedTextureHandle newHandle = texture.handle();
|
||||
mSize = texture.size();
|
||||
mInverted = texture.inverted();
|
||||
|
||||
if (mSharedHandle && newHandle != mSharedHandle)
|
||||
gl()->ReleaseSharedHandle(mShareType, mSharedHandle);
|
||||
|
||||
mSharedHandle = newHandle;
|
||||
mShareType = texture.shareType();
|
||||
} else {
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, surface);
|
||||
gfxIntSize size = surf.Size();
|
||||
if (mSize != size || !mTexImage ||
|
||||
mTexImage->GetContentType() != surf.ContentType()) {
|
||||
Init(aNewFront);
|
||||
}
|
||||
// XXX this is always just ridiculously slow
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
|
||||
mTexImage->DirectUpdate(surf.Get(), updateRegion);
|
||||
AutoOpenSurface surf(OPEN_READ_ONLY, aNewFront.get_SurfaceDescriptor());
|
||||
gfxIntSize size = surf.Size();
|
||||
if (mSize != size || !mTexImage ||
|
||||
mTexImage->GetContentType() != surf.ContentType()) {
|
||||
Init(aNewFront);
|
||||
}
|
||||
// XXX this is always just ridiculously slow
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
|
||||
mTexImage->DirectUpdate(surf.Get(), updateRegion);
|
||||
} else {
|
||||
const YUVImage& yuv = aNewFront.get_YUVImage();
|
||||
UploadSharedYUVToTexture(yuv);
|
||||
@ -927,39 +880,7 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
mTexImage->GetTileRect().Size());
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
} else if (mSharedHandle) {
|
||||
GLContext::SharedHandleDetails handleDetails;
|
||||
if (!gl()->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) {
|
||||
NS_ERROR("Failed to get shared handle details");
|
||||
return;
|
||||
}
|
||||
|
||||
ShaderProgramOGL* program = mOGLManager->GetProgram(handleDetails.mProgramType, GetMaskLayer());
|
||||
|
||||
program->Activate();
|
||||
program->SetLayerTransform(GetEffectiveTransform());
|
||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||
program->SetRenderOffset(aOffset);
|
||||
program->SetTextureUnit(0);
|
||||
program->SetTextureTransform(handleDetails.mTextureTransform);
|
||||
program->LoadMask(GetMaskLayer());
|
||||
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(handleDetails.mTarget, mTexture);
|
||||
|
||||
if (!gl()->AttachSharedHandle(mShareType, mSharedHandle)) {
|
||||
NS_ERROR("Failed to bind shared texture handle");
|
||||
return;
|
||||
}
|
||||
|
||||
gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
|
||||
LOCAL_GL_ONE, LOCAL_GL_ONE);
|
||||
gl()->ApplyFilterToBoundTexture(mFilter);
|
||||
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mSize));
|
||||
mOGLManager->BindAndDrawQuad(program, mInverted);
|
||||
gl()->fBindTexture(handleDetails.mTarget, 0);
|
||||
gl()->DetachSharedHandle(mShareType, mSharedHandle);
|
||||
} else {
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID());
|
||||
@ -1011,11 +932,6 @@ ShadowImageLayerOGL::LoadAsTexture(GLuint aTextureUnit, gfxIntSize* aSize)
|
||||
void
|
||||
ShadowImageLayerOGL::CleanupResources()
|
||||
{
|
||||
if (mSharedHandle) {
|
||||
gl()->ReleaseSharedHandle(mShareType, mSharedHandle);
|
||||
mSharedHandle = NULL;
|
||||
}
|
||||
|
||||
mYUVTexture[0].Release();
|
||||
mYUVTexture[1].Release();
|
||||
mYUVTexture[2].Release();
|
||||
|
@ -180,13 +180,6 @@ private:
|
||||
|
||||
|
||||
nsRefPtr<TextureImage> mTexImage;
|
||||
|
||||
// For SharedTextureHandle
|
||||
gl::SharedTextureHandle mSharedHandle;
|
||||
gl::TextureImage::TextureShareType mShareType;
|
||||
bool mInverted;
|
||||
GLuint mTexture;
|
||||
|
||||
GLTexture mYUVTexture[3];
|
||||
gfxIntSize mSize;
|
||||
gfxIntSize mCbCrSize;
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "TiledThebesLayerOGL.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "TexturePoolOGL.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxUtils.h"
|
||||
@ -752,10 +751,6 @@ LayerManagerOGL::Render()
|
||||
MakeCurrent();
|
||||
}
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
TexturePoolOGL::Fill(gl());
|
||||
#endif
|
||||
|
||||
SetupBackBuffer(width, height);
|
||||
SetupPipeline(width, height, ApplyWorldTransform);
|
||||
|
||||
|
@ -53,23 +53,6 @@ ProgramProfileOGL::GetProfileFor(gl::ShaderProgramType aType,
|
||||
AddCommonTextureArgs(result);
|
||||
result.mTextureCount = 1;
|
||||
break;
|
||||
case gl::RGBALayerExternalProgramType:
|
||||
if (aMask == Mask3d) {
|
||||
result.mVertexShaderString = sLayerMask3DVS;
|
||||
result.mFragmentShaderString = sRGBATextureLayerExternalMask3DFS;
|
||||
} else if (aMask == Mask2d) {
|
||||
result.mVertexShaderString = sLayerMaskVS;
|
||||
result.mFragmentShaderString = sRGBATextureLayerExternalMaskFS;
|
||||
} else {
|
||||
result.mVertexShaderString = sLayerVS;
|
||||
result.mFragmentShaderString = sRGBATextureLayerExternalFS;
|
||||
}
|
||||
AddCommonArgs(result);
|
||||
AddCommonTextureArgs(result);
|
||||
result.mUniforms.AppendElement(Argument("uTextureTransform"));
|
||||
result.mHasTextureTransform = true;
|
||||
result.mTextureCount = 1;
|
||||
break;
|
||||
case gl::BGRALayerProgramType:
|
||||
if (aMask == Mask2d) {
|
||||
result.mVertexShaderString = sLayerMaskVS;
|
||||
|
@ -111,12 +111,10 @@ struct ProgramProfileOGL
|
||||
nsTArray<Argument> mAttributes;
|
||||
PRUint32 mTextureCount;
|
||||
bool mHasMatrixProj;
|
||||
bool mHasTextureTransform;
|
||||
private:
|
||||
ProgramProfileOGL() :
|
||||
mTextureCount(0),
|
||||
mHasMatrixProj(false),
|
||||
mHasTextureTransform(false) {}
|
||||
mHasMatrixProj(false) {}
|
||||
};
|
||||
|
||||
|
||||
@ -144,6 +142,7 @@ public:
|
||||
mIsProjectionMatrixStale(false), mGL(aGL), mProgram(0),
|
||||
mProfile(aProfile), mProgramState(STATE_NEW) { }
|
||||
|
||||
|
||||
~ShaderProgramOGL() {
|
||||
if (mProgram <= 0) {
|
||||
return;
|
||||
@ -247,12 +246,6 @@ public:
|
||||
mIsProjectionMatrixStale = false;
|
||||
}
|
||||
|
||||
// sets this program's texture transform, if it uses one
|
||||
void SetTextureTransform(const gfx3DMatrix& aMatrix) {
|
||||
if (mProfile.mHasTextureTransform)
|
||||
SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
|
||||
}
|
||||
|
||||
void SetRenderOffset(const nsIntPoint& aOffset) {
|
||||
float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
|
||||
SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
|
||||
|
@ -232,91 +232,6 @@ gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
static const char sRGBATextureLayerExternalFS[] = "/* sRGBATextureLayerExternalFS */\n\
|
||||
/* Fragment Shader */\n\
|
||||
#ifdef GL_ES\n\
|
||||
precision lowp float;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#ifndef NO_LAYER_OPACITY\n\
|
||||
uniform float uLayerOpacity;\n\
|
||||
#endif\n\
|
||||
#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
|
||||
varying mediump vec2 vTexCoord;\n\
|
||||
#else\n\
|
||||
varying vec2 vTexCoord;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#extension GL_OES_EGL_image_external : require\n\
|
||||
uniform samplerExternalOES uTexture;\n\
|
||||
uniform mat4 uTextureTransform;\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
float mask = 1.0;\n\
|
||||
\n\
|
||||
gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
static const char sRGBATextureLayerExternalMaskFS[] = "/* sRGBATextureLayerExternalMaskFS */\n\
|
||||
/* Fragment Shader */\n\
|
||||
#ifdef GL_ES\n\
|
||||
precision lowp float;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#ifndef NO_LAYER_OPACITY\n\
|
||||
uniform float uLayerOpacity;\n\
|
||||
#endif\n\
|
||||
#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
|
||||
varying mediump vec2 vTexCoord;\n\
|
||||
#else\n\
|
||||
varying vec2 vTexCoord;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
varying vec2 vMaskCoord;\n\
|
||||
uniform sampler2D uMaskTexture;\n\
|
||||
\n\
|
||||
#extension GL_OES_EGL_image_external : require\n\
|
||||
uniform samplerExternalOES uTexture;\n\
|
||||
uniform mat4 uTextureTransform;\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
|
||||
\n\
|
||||
gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
static const char sRGBATextureLayerExternalMask3DFS[] = "/* sRGBATextureLayerExternalMask3DFS */\n\
|
||||
/* Fragment Shader */\n\
|
||||
#ifdef GL_ES\n\
|
||||
precision lowp float;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#ifndef NO_LAYER_OPACITY\n\
|
||||
uniform float uLayerOpacity;\n\
|
||||
#endif\n\
|
||||
#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
|
||||
varying mediump vec2 vTexCoord;\n\
|
||||
#else\n\
|
||||
varying vec2 vTexCoord;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
varying vec3 vMaskCoord;\n\
|
||||
uniform sampler2D uMaskTexture;\n\
|
||||
\n\
|
||||
#extension GL_OES_EGL_image_external : require\n\
|
||||
uniform samplerExternalOES uTexture;\n\
|
||||
uniform mat4 uTextureTransform;\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
|
||||
float mask = texture2D(uMaskTexture, maskCoords).r;\n\
|
||||
\n\
|
||||
gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
static const char sRGBARectTextureLayerFS[] = "/* sRGBARectTextureLayerFS */\n\
|
||||
#extension GL_ARB_texture_rectangle : enable\n\
|
||||
/* Fragment Shader */\n\
|
||||
|
@ -211,20 +211,6 @@ $FRAGMENT_CALC_MASK<mask>$
|
||||
}
|
||||
@end
|
||||
|
||||
// Single texture in RGBA format for use with GL_TEXTURE_EXTERNAL_OES
|
||||
@shader sRGBATextureLayerExternal<mask:,Mask,Mask3D>FS
|
||||
$LAYER_FRAGMENT<mask>$
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
uniform samplerExternalOES uTexture;
|
||||
uniform mat4 uTextureTransform;
|
||||
|
||||
void main()
|
||||
{
|
||||
$FRAGMENT_CALC_MASK<mask>$
|
||||
gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
// Single texture in RGBA format, but with a Rect texture.
|
||||
// Container layer needs this to render a FBO group.
|
||||
|
@ -1,115 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TexturePoolOGL.h"
|
||||
#include "GLContext.h"
|
||||
#include "nsDeque.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
#define TEXTURE_POOL_SIZE 10
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
static GLContext* sActiveContext = NULL;
|
||||
|
||||
static Monitor* sMonitor = NULL;
|
||||
static nsDeque* sTextures = NULL;
|
||||
|
||||
GLuint TexturePoolOGL::AcquireTexture()
|
||||
{
|
||||
NS_ASSERTION(sMonitor, "not initialized");
|
||||
|
||||
MonitorAutoLock lock(*sMonitor);
|
||||
|
||||
if (!sActiveContext) {
|
||||
// Wait for a context
|
||||
sMonitor->Wait();
|
||||
|
||||
if (!sActiveContext)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint texture = 0;
|
||||
if (sActiveContext->IsOwningThreadCurrent()) {
|
||||
sActiveContext->MakeCurrent();
|
||||
|
||||
sActiveContext->fGenTextures(1, &texture);
|
||||
} else {
|
||||
while (sTextures->GetSize() == 0) {
|
||||
NS_WARNING("Waiting for texture");
|
||||
sMonitor->Wait();
|
||||
}
|
||||
|
||||
GLuint* popped = (GLuint*) sTextures->Pop();
|
||||
if (!popped) {
|
||||
NS_ERROR("Failed to pop texture pool item");
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture = *popped;
|
||||
delete popped;
|
||||
|
||||
NS_ASSERTION(texture, "Failed to retrieve texture from pool");
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void Clear()
|
||||
{
|
||||
if (!sActiveContext)
|
||||
return;
|
||||
|
||||
sActiveContext->MakeCurrent();
|
||||
|
||||
GLuint* item;
|
||||
while (sTextures->GetSize()) {
|
||||
item = (GLuint*)sTextures->Pop();
|
||||
sActiveContext->fDeleteTextures(1, item);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
void TexturePoolOGL::Fill(GLContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aContext, "NULL GLContext");
|
||||
NS_ASSERTION(sMonitor, "not initialized");
|
||||
|
||||
MonitorAutoLock lock(*sMonitor);
|
||||
|
||||
if (sActiveContext != aContext) {
|
||||
Clear();
|
||||
sActiveContext = aContext;
|
||||
}
|
||||
|
||||
if (sTextures->GetSize() == TEXTURE_POOL_SIZE)
|
||||
return;
|
||||
|
||||
sActiveContext->MakeCurrent();
|
||||
|
||||
GLuint* texture = NULL;
|
||||
while (sTextures->GetSize() < TEXTURE_POOL_SIZE) {
|
||||
texture = (GLuint*)malloc(sizeof(GLuint));
|
||||
sActiveContext->fGenTextures(1, texture);
|
||||
sTextures->Push((void*) texture);
|
||||
}
|
||||
|
||||
sMonitor->NotifyAll();
|
||||
}
|
||||
|
||||
void TexturePoolOGL::Init()
|
||||
{
|
||||
sMonitor = new Monitor("TexturePoolOGL.sMonitor");
|
||||
sTextures = new nsDeque();
|
||||
}
|
||||
|
||||
void TexturePoolOGL::Shutdown()
|
||||
{
|
||||
delete sMonitor;
|
||||
delete sTextures;
|
||||
}
|
||||
|
||||
} // gl
|
||||
} // mozilla
|
@ -1,38 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_TEXTUREPOOLOGL_H
|
||||
#define GFX_TEXTUREPOOLOGL_H
|
||||
|
||||
#include "GLContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
// A texture pool for for the on-screen GLContext. The main purpose of this class
|
||||
// is to provide the ability to easily allocate an on-screen texture from the
|
||||
// content thread. The unfortunate nature of the SurfaceTexture API (see nsSurfaceTexture)
|
||||
// necessitates this.
|
||||
class TexturePoolOGL
|
||||
{
|
||||
public:
|
||||
// Get a new texture from the pool. Will block
|
||||
// and wait for one to be created if necessary
|
||||
static GLuint AcquireTexture();
|
||||
|
||||
// Called by the active LayerManagerOGL to fill
|
||||
// the pool
|
||||
static void Fill(GLContext* aContext);
|
||||
|
||||
// Initializes the pool, but does not fill it. Called by gfxPlatform init.
|
||||
static void Init();
|
||||
|
||||
// Clears all internal data structures in preparation for shutdown
|
||||
static void Shutdown();
|
||||
};
|
||||
|
||||
} // gl
|
||||
} // mozilla
|
||||
|
||||
#endif // GFX_TEXTUREPOOLOGL_H
|
@ -49,7 +49,6 @@ EXPORTS = \
|
||||
gfxUserFontSet.h \
|
||||
nsCoreAnimationSupport.h \
|
||||
nsIOSurface.h \
|
||||
nsSurfaceTexture.h \
|
||||
gfxSharedImageSurface.h \
|
||||
gfxReusableSurfaceWrapper.h \
|
||||
$(NULL)
|
||||
@ -175,7 +174,6 @@ CPPSRCS = \
|
||||
gfxHarfBuzzShaper.cpp \
|
||||
gfxSharedImageSurface.cpp \
|
||||
gfxReusableSurfaceWrapper.cpp \
|
||||
nsSurfaceTexture.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
|
||||
|
@ -59,10 +59,6 @@
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "TexturePoolOGL.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
@ -339,11 +335,6 @@ gfxPlatform::Init()
|
||||
|
||||
gPlatform->mWorkAroundDriverBugs = Preferences::GetBool("gfx.work-around-driver-bugs", true);
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// Texture pool init
|
||||
mozilla::gl::TexturePoolOGL::Init();
|
||||
#endif
|
||||
|
||||
// Force registration of the gfx component, thus arranging for
|
||||
// ::Shutdown to be called.
|
||||
nsCOMPtr<nsISupports> forceReg
|
||||
@ -380,11 +371,6 @@ gfxPlatform::Shutdown()
|
||||
gPlatform->mFontPrefsObserver = nsnull;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// Shut down the texture pool
|
||||
mozilla::gl::TexturePoolOGL::Shutdown();
|
||||
#endif
|
||||
|
||||
// Shut down the default GL context provider.
|
||||
mozilla::gl::GLContextProvider::Shutdown();
|
||||
|
||||
|
@ -1,263 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <android/log.h>
|
||||
#include "nsSurfaceTexture.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsSurfaceTexture" , ## args)
|
||||
|
||||
// UGH
|
||||
static std::map<int, nsSurfaceTexture*> sInstances;
|
||||
static int sNextID = 0;
|
||||
|
||||
static class JNIFunctions {
|
||||
public:
|
||||
|
||||
JNIFunctions() : mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool EnsureInitialized()
|
||||
{
|
||||
if (mInitialized)
|
||||
return true;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return false;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
jSurfaceTextureClass = (jclass)env->NewGlobalRef(env->FindClass("android/graphics/SurfaceTexture"));
|
||||
jSurfaceTexture_Ctor = env->GetMethodID(jSurfaceTextureClass, "<init>", "(I)V");
|
||||
jSurfaceTexture_updateTexImage = env->GetMethodID(jSurfaceTextureClass, "updateTexImage", "()V");
|
||||
jSurfaceTexture_getTransformMatrix = env->GetMethodID(jSurfaceTextureClass, "getTransformMatrix", "([F)V");
|
||||
|
||||
mInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
jobject CreateSurfaceTexture(GLuint aTexture)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return NULL;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
return env->NewGlobalRef(env->NewObject(jSurfaceTextureClass, jSurfaceTexture_Ctor, (int) aTexture));
|
||||
}
|
||||
|
||||
void ReleaseSurfaceTexture(jobject aSurfaceTexture)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
env->DeleteGlobalRef(aSurfaceTexture);
|
||||
}
|
||||
|
||||
void UpdateTexImage(jobject aSurfaceTexture)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
env->CallObjectMethod(aSurfaceTexture, jSurfaceTexture_updateTexImage);
|
||||
}
|
||||
|
||||
bool GetTransformMatrix(jobject aSurfaceTexture, gfx3DMatrix& aMatrix)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return false;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
jfloatArray jarray = env->NewFloatArray(16);
|
||||
env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_getTransformMatrix, jarray);
|
||||
|
||||
jfloat* array = env->GetFloatArrayElements(jarray, NULL);
|
||||
|
||||
aMatrix._11 = array[0];
|
||||
aMatrix._12 = array[1];
|
||||
aMatrix._13 = array[2];
|
||||
aMatrix._14 = array[3];
|
||||
|
||||
aMatrix._21 = array[4];
|
||||
aMatrix._22 = array[5];
|
||||
aMatrix._23 = array[6];
|
||||
aMatrix._24 = array[7];
|
||||
|
||||
aMatrix._31 = array[8];
|
||||
aMatrix._32 = array[9];
|
||||
aMatrix._33 = array[10];
|
||||
aMatrix._34 = array[11];
|
||||
|
||||
aMatrix._41 = array[12];
|
||||
aMatrix._42 = array[13];
|
||||
aMatrix._43 = array[14];
|
||||
aMatrix._44 = array[15];
|
||||
|
||||
env->ReleaseFloatArrayElements(jarray, array, 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mInitialized;
|
||||
|
||||
jclass jSurfaceTextureClass;
|
||||
jmethodID jSurfaceTexture_Ctor;
|
||||
jmethodID jSurfaceTexture_updateTexImage;
|
||||
jmethodID jSurfaceTexture_getTransformMatrix;
|
||||
|
||||
} sJNIFunctions;
|
||||
|
||||
nsSurfaceTexture*
|
||||
nsSurfaceTexture::Create(GLuint aTexture)
|
||||
{
|
||||
// Right now we only support creating this on the main thread because
|
||||
// of the JNIEnv assumptions in JNIHelper and elsewhere
|
||||
if (!NS_IsMainThread())
|
||||
return NULL;
|
||||
|
||||
nsSurfaceTexture* st = new nsSurfaceTexture();
|
||||
if (!st->Init(aTexture)) {
|
||||
LOG("Failed to initialize nsSurfaceTexture");
|
||||
delete st;
|
||||
st = NULL;
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
nsSurfaceTexture*
|
||||
nsSurfaceTexture::Find(int id)
|
||||
{
|
||||
std::map<int, nsSurfaceTexture*>::iterator it;
|
||||
|
||||
it = sInstances.find(id);
|
||||
if (it == sInstances.end())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool
|
||||
nsSurfaceTexture::Check()
|
||||
{
|
||||
return sJNIFunctions.EnsureInitialized();
|
||||
}
|
||||
|
||||
bool
|
||||
nsSurfaceTexture::Init(GLuint aTexture)
|
||||
{
|
||||
if (!sJNIFunctions.EnsureInitialized())
|
||||
return false;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return false;
|
||||
|
||||
mSurfaceTexture = sJNIFunctions.CreateSurfaceTexture(aTexture);
|
||||
if (!mSurfaceTexture)
|
||||
return false;
|
||||
|
||||
mNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindowFromSurfaceTexture(env, mSurfaceTexture);
|
||||
|
||||
mID = ++sNextID;
|
||||
sInstances.insert(std::pair<int, nsSurfaceTexture*>(mID, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsSurfaceTexture::nsSurfaceTexture()
|
||||
: mSurfaceTexture(NULL), mNativeWindow(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
nsSurfaceTexture::~nsSurfaceTexture()
|
||||
{
|
||||
sInstances.erase(mID);
|
||||
|
||||
mFrameAvailableCallback = NULL;
|
||||
|
||||
if (mNativeWindow) {
|
||||
AndroidBridge::Bridge()->ReleaseNativeWindowForSurfaceTexture(mSurfaceTexture);
|
||||
mNativeWindow = NULL;
|
||||
}
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
if (mSurfaceTexture && env) {
|
||||
AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
|
||||
|
||||
env->DeleteGlobalRef(mSurfaceTexture);
|
||||
mSurfaceTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
nsSurfaceTexture::GetNativeWindow()
|
||||
{
|
||||
return mNativeWindow;
|
||||
}
|
||||
|
||||
void
|
||||
nsSurfaceTexture::UpdateTexImage()
|
||||
{
|
||||
sJNIFunctions.UpdateTexImage(mSurfaceTexture);
|
||||
}
|
||||
|
||||
bool
|
||||
nsSurfaceTexture::GetTransformMatrix(gfx3DMatrix& aMatrix)
|
||||
{
|
||||
return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix);
|
||||
}
|
||||
|
||||
void
|
||||
nsSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
|
||||
{
|
||||
if (aRunnable)
|
||||
AndroidBridge::Bridge()->RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
|
||||
else
|
||||
AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
|
||||
|
||||
mFrameAvailableCallback = aRunnable;
|
||||
}
|
||||
|
||||
void
|
||||
nsSurfaceTexture::NotifyFrameAvailable()
|
||||
{
|
||||
if (mFrameAvailableCallback) {
|
||||
// Proxy to main thread if we aren't on it
|
||||
if (!NS_IsMainThread()) {
|
||||
// Proxy to main thread
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &nsSurfaceTexture::NotifyFrameAvailable);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
} else {
|
||||
mFrameAvailableCallback->Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
@ -1,64 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsSurfaceTexture_h__
|
||||
#define nsSurfaceTexture_h__
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
#include <jni.h>
|
||||
#include "nsIRunnable.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "GLDefs.h"
|
||||
|
||||
class gfxASurface;
|
||||
|
||||
/**
|
||||
* This class is a wrapper around Android's SurfaceTexture class.
|
||||
* Usage is pretty much exactly like the Java class, so see
|
||||
* the Android documentation for details.
|
||||
*/
|
||||
class THEBES_API nsSurfaceTexture {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsSurfaceTexture)
|
||||
|
||||
public:
|
||||
static nsSurfaceTexture* Create(GLuint aTexture);
|
||||
static nsSurfaceTexture* Find(int id);
|
||||
|
||||
// Returns with reasonable certainty whether or not we'll
|
||||
// be able to create and use a SurfaceTexture
|
||||
static bool Check();
|
||||
|
||||
~nsSurfaceTexture();
|
||||
|
||||
// This is an ANativeWindow. Use AndroidBridge::LockWindow and
|
||||
// friends for manipulating it.
|
||||
void* GetNativeWindow();
|
||||
|
||||
// This attaches the updated data to the TEXTURE_EXTERNAL target
|
||||
void UpdateTexImage();
|
||||
|
||||
bool GetTransformMatrix(gfx3DMatrix& aMatrix);
|
||||
int ID() { return mID; }
|
||||
|
||||
void SetFrameAvailableCallback(nsIRunnable* aRunnable);
|
||||
|
||||
// Only should be called by AndroidJNI when we get a
|
||||
// callback from the underlying SurfaceTexture instance
|
||||
void NotifyFrameAvailable();
|
||||
private:
|
||||
nsSurfaceTexture();
|
||||
|
||||
bool Init(GLuint aTexture);
|
||||
|
||||
jobject mSurfaceTexture;
|
||||
void* mNativeWindow;
|
||||
int mID;
|
||||
nsRefPtr<nsIRunnable> mFrameAvailableCallback;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
@ -198,7 +198,6 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
-I $(DEPTH)/dist/idl \
|
||||
--header-output DictionaryHelpers.h \
|
||||
--stub-output DictionaryHelpers.cpp \
|
||||
--makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \
|
||||
$(srcdir)/dictionary_helper_gen.conf \
|
||||
|
@ -7709,7 +7709,7 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame,
|
||||
!(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG)) {
|
||||
if (aChange & nsChangeHint_UpdateEffects) {
|
||||
// Invalidate and update our area:
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(aFrame);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(aFrame);
|
||||
} else {
|
||||
// Just invalidate our area:
|
||||
nsSVGUtils::InvalidateBounds(aFrame);
|
||||
|
@ -49,7 +49,6 @@ enum Type {
|
||||
TYPE_PAGE_SEQUENCE,
|
||||
TYPE_PLUGIN,
|
||||
TYPE_PLUGIN_READBACK,
|
||||
TYPE_PLUGIN_VIDEO,
|
||||
TYPE_PRINT_PLUGIN,
|
||||
TYPE_REMOTE,
|
||||
TYPE_REMOTE_SHADOW,
|
||||
|
@ -1008,8 +1008,10 @@ public:
|
||||
void AppendToBottom(nsDisplayList* aList) {
|
||||
if (aList->mSentinel.mAbove) {
|
||||
aList->mTop->mAbove = mSentinel.mAbove;
|
||||
mTop = aList->mTop;
|
||||
mSentinel.mAbove = aList->mSentinel.mAbove;
|
||||
if (mTop == &mSentinel) {
|
||||
mTop = aList->mTop;
|
||||
}
|
||||
|
||||
aList->mTop = &aList->mSentinel;
|
||||
aList->mSentinel.mAbove = nsnull;
|
||||
|
@ -6928,7 +6928,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
|
||||
Invalidate(aOverflowAreas.VisualOverflow());
|
||||
}
|
||||
}
|
||||
// XXXSDL For SVG the invalidation happens in UpdateBounds for now, so we
|
||||
// XXXSDL For SVG the invalidation happens in ReflowSVG for now, so we
|
||||
// don't currently invalidate SVG here:
|
||||
if (anyOverflowChanged && hasTransform &&
|
||||
!(GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
|
||||
|
@ -145,11 +145,6 @@ using mozilla::DefaultXDisplay;
|
||||
#include "gfxOS2Surface.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#include "GLContext.h"
|
||||
#endif
|
||||
|
||||
#ifdef CreateEvent // Thank you MS.
|
||||
#undef CreateEvent
|
||||
#endif
|
||||
@ -937,66 +932,6 @@ nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class nsDisplayPluginVideo : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayPluginVideo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
|
||||
: nsDisplayItem(aBuilder, aFrame), mVideoInfo(aVideoInfo)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayPluginVideo);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayPluginVideo() {
|
||||
MOZ_COUNT_DTOR(nsDisplayPluginVideo);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
|
||||
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion);
|
||||
|
||||
NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO)
|
||||
|
||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters)
|
||||
{
|
||||
return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this);
|
||||
}
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance::VideoInfo* VideoInfo() { return mVideoInfo; }
|
||||
|
||||
private:
|
||||
nsNPAPIPluginInstance::VideoInfo* mVideoInfo;
|
||||
};
|
||||
|
||||
nsRect
|
||||
nsDisplayPluginVideo::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
||||
{
|
||||
*aSnap = false;
|
||||
return GetDisplayItemBounds(aBuilder, this, mFrame);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayPluginVideo::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion)
|
||||
{
|
||||
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
|
||||
aAllowVisibleRegionExpansion);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nsRect
|
||||
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
||||
{
|
||||
@ -1151,9 +1086,6 @@ nsObjectFrame::IsOpaque() const
|
||||
#if defined(XP_MACOSX)
|
||||
// ???
|
||||
return false;
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
// We don't know, so just assume transparent
|
||||
return false;
|
||||
#else
|
||||
return !IsTransparentMode();
|
||||
#endif
|
||||
@ -1242,8 +1174,6 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayGeneric(aBuilder, this, PaintPrintPlugin, "PrintPlugin",
|
||||
nsDisplayItem::TYPE_PRINT_PLUGIN));
|
||||
} else {
|
||||
// We don't need this on Android, and it just confuses things
|
||||
#if !MOZ_WIDGET_ANDROID
|
||||
if (aBuilder->IsPaintingToWindow() &&
|
||||
GetLayerState(aBuilder, nsnull) == LAYER_ACTIVE &&
|
||||
IsTransparentMode()) {
|
||||
@ -1251,22 +1181,6 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayPluginReadback(aBuilder, this));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
if (aBuilder->IsPaintingToWindow() &&
|
||||
GetLayerState(aBuilder, nsnull) == LAYER_ACTIVE) {
|
||||
|
||||
nsTArray<nsNPAPIPluginInstance::VideoInfo*> videos;
|
||||
mInstanceOwner->GetVideos(videos);
|
||||
|
||||
for (int i = 0; i < videos.Length(); i++) {
|
||||
rv = replacedContent.AppendNewToTop(new (aBuilder)
|
||||
nsDisplayPluginVideo(aBuilder, this, videos[i]));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = replacedContent.AppendNewToTop(new (aBuilder)
|
||||
nsDisplayPlugin(aBuilder, this));
|
||||
@ -1574,12 +1488,6 @@ nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// We always want a layer on Honeycomb and later
|
||||
if (AndroidBridge::Bridge()->GetAPIVersion() >= 11)
|
||||
return LAYER_ACTIVE;
|
||||
#endif
|
||||
|
||||
if (!mInstanceOwner->UseAsyncRendering()) {
|
||||
return LAYER_NONE;
|
||||
}
|
||||
@ -1658,32 +1566,6 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
imglayer->SetFilter(filter);
|
||||
|
||||
layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
} else if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_VIDEO) {
|
||||
nsDisplayPluginVideo* videoItem = reinterpret_cast<nsDisplayPluginVideo*>(aItem);
|
||||
nsNPAPIPluginInstance::VideoInfo* videoInfo = videoItem->VideoInfo();
|
||||
|
||||
nsRefPtr<ImageContainer> container = mInstanceOwner->GetImageContainerForVideo(videoInfo);
|
||||
if (!container)
|
||||
return nsnull;
|
||||
|
||||
if (!layer) {
|
||||
// Initialize ImageLayer
|
||||
layer = aManager->CreateImageLayer();
|
||||
if (!layer)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
|
||||
imglayer->SetContainer(container);
|
||||
|
||||
layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
|
||||
|
||||
// Set the offset and size according to the video dimensions
|
||||
r.MoveBy(videoInfo->mDimensions.TopLeft());
|
||||
size.width = videoInfo->mDimensions.width;
|
||||
size.height = videoInfo->mDimensions.height;
|
||||
#endif
|
||||
} else {
|
||||
NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK,
|
||||
"Unknown item type");
|
||||
|
21
layout/reftests/svg/pattern-transformed-01-ref.svg
Normal file
21
layout/reftests/svg/pattern-transformed-01-ref.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<pattern x="0" y="0" width="1" height="1" id="pattern" patternContentUnits="objectBoundingBox">
|
||||
<rect width="1" height="1" fill="red"/>
|
||||
<rect width="1" height="1" fill="url(#gradient)"/>
|
||||
</pattern>
|
||||
|
||||
<linearGradient id="gradient" x1="0" y1="1" x2="0" y2="0">
|
||||
<stop offset="0%" stop-color="black" stop-opacity="1"/>
|
||||
<stop offset="100%" stop-color="black" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
|
||||
<circle r="120" cx="120" cy="120" fill="url(#pattern)"/>
|
||||
|
||||
<path
|
||||
transform="matrix(1,0,0,1,360,120)"
|
||||
d="M0 0M 120 0 A 120 120 0 0 0 -120 0 A 120 120 0 0 0 120 0"
|
||||
fill="url(#pattern)"/>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 697 B |
28
layout/reftests/svg/pattern-transformed-01.svg
Normal file
28
layout/reftests/svg/pattern-transformed-01.svg
Normal file
@ -0,0 +1,28 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=773595 -->
|
||||
|
||||
<pattern x="0" y="0" width="1" height="1" id="pattern">
|
||||
<rect width="240" height="240" fill="red"/>
|
||||
<rect width="240" height="240" fill="url(#gradient)"/>
|
||||
</pattern>
|
||||
|
||||
<linearGradient id="gradient" x1="0" y1="1" x2="0" y2="0">
|
||||
<stop offset="0%" stop-color="black" stop-opacity="1"/>
|
||||
<stop offset="100%" stop-color="black" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
|
||||
<circle r="120" cx="120" cy="0" fill="url(#pattern)"
|
||||
transform="translate(0,120)"/>
|
||||
|
||||
<path
|
||||
transform="translate(0,120)"
|
||||
d="M 480 0 A 120 120 0 0 0 240 0 A 120 120 0 0 0 480 0"
|
||||
fill="url(#pattern)"/>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 873 B |
@ -209,6 +209,7 @@ random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-02.svg objectBoundin
|
||||
== pattern-scale-01a.svg pattern-scale-01-ref.svg
|
||||
== pattern-scale-01b.svg pattern-scale-01-ref.svg
|
||||
== pattern-transform-presence-01.svg pattern-transform-presence-01-ref.svg
|
||||
== pattern-transformed-01.svg pattern-transformed-01-ref.svg
|
||||
== polygon-marker-01.svg pass.svg
|
||||
== polygon-points-negative-01.svg pass.svg
|
||||
== polyline-points-invalid-01.svg pass.svg
|
||||
|
@ -8362,7 +8362,7 @@ bool CSSParserImpl::ParseTransformOrigin(bool aPerspective)
|
||||
nsCSSValue depth;
|
||||
if (!ParseVariant(depth, VARIANT_LENGTH | VARIANT_CALC, nsnull) ||
|
||||
!nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
depth.Reset();
|
||||
depth.SetFloatValue(0.0f, eCSSUnit_Pixel);
|
||||
}
|
||||
value.SetTripletValue(position.mXValue, position.mYValue, depth);
|
||||
}
|
||||
|
@ -423,10 +423,10 @@ void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
|
||||
void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
|
||||
{
|
||||
// triplet should not be used for null/inherit/initial values
|
||||
// Only allow Null for the z component
|
||||
NS_ABORT_IF_FALSE(aValue &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
|
@ -563,7 +563,7 @@ nsStyleAnimation::ComputeDistance(nsCSSProperty aProperty,
|
||||
unit[2] = GetCommonUnit(aProperty, triplet1->mZValue.GetUnit(),
|
||||
triplet2->mZValue.GetUnit());
|
||||
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
|
||||
unit[0] == eCSSUnit_URL) {
|
||||
unit[2] == eCSSUnit_Null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1781,13 +1781,6 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
|
||||
nsCSSValueTriplet triplet1(*aValue1.GetCSSValueTripletValue());
|
||||
nsCSSValueTriplet triplet2(*aValue2.GetCSSValueTripletValue());
|
||||
|
||||
if (triplet1.mZValue.GetUnit() == eCSSUnit_Null) {
|
||||
triplet1.mZValue.SetFloatValue(0.0, eCSSUnit_Pixel);
|
||||
}
|
||||
if (triplet2.mZValue.GetUnit() == eCSSUnit_Null) {
|
||||
triplet2.mZValue.SetFloatValue(0.0, eCSSUnit_Pixel);
|
||||
}
|
||||
|
||||
nsCSSUnit unit[3];
|
||||
unit[0] = GetCommonUnit(aProperty, triplet1.mXValue.GetUnit(),
|
||||
triplet2.mXValue.GetUnit());
|
||||
@ -1796,7 +1789,7 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
|
||||
unit[2] = GetCommonUnit(aProperty, triplet1.mZValue.GetUnit(),
|
||||
triplet2.mZValue.GetUnit());
|
||||
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
|
||||
unit[0] == eCSSUnit_Null || unit[0] == eCSSUnit_URL) {
|
||||
unit[2] == eCSSUnit_Null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1816,11 +1809,6 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
|
||||
}
|
||||
}
|
||||
|
||||
if (result->mZValue.GetUnit() == eCSSUnit_Pixel &&
|
||||
result->mZValue.GetFloatValue() == 0.0f) {
|
||||
result->mZValue.Reset();
|
||||
}
|
||||
|
||||
aResultValue.SetAndAdoptCSSValueTripletValue(result.forget(),
|
||||
eUnit_CSSValueTriplet);
|
||||
return true;
|
||||
@ -2673,10 +2661,6 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
|
||||
triplet->mZValue)) {
|
||||
return false;
|
||||
}
|
||||
if (triplet->mZValue.GetUnit() == eCSSUnit_Pixel &&
|
||||
triplet->mZValue.GetFloatValue() == 0.0f) {
|
||||
triplet->mZValue.Reset();
|
||||
}
|
||||
aComputedValue.SetAndAdoptCSSValueTripletValue(triplet.forget(),
|
||||
eUnit_CSSValueTriplet);
|
||||
break;
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
// called until after the nsSVGOuterSVGFrame has had its initial reflow
|
||||
// (i.e. once the SVG viewport dimensions are known). It should also only
|
||||
// be called by nsSVGOuterSVGFrame during its reflow.
|
||||
virtual void UpdateBounds()=0;
|
||||
virtual void ReflowSVG()=0;
|
||||
|
||||
/**
|
||||
* Flags used to specify to GetCanvasTM what it's being called for so that it
|
||||
|
@ -107,7 +107,7 @@ nsSVGAFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::transform) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifySVGChanged(TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ nsSVGDisplayContainerFrame::InsertFrames(ChildListID aListID,
|
||||
NS_FRAME_HAS_DIRTY_CHILDREN);
|
||||
// No need to invalidate the new kid's old bounds, so we just use
|
||||
// nsSVGUtils::ScheduleBoundsUpdate.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(kid);
|
||||
nsSVGUtils::ScheduleReflowSVG(kid);
|
||||
if (isFirstReflow) {
|
||||
// Add back the NS_FRAME_FIRST_REFLOW bit:
|
||||
kid->AddStateBits(NS_FRAME_FIRST_REFLOW);
|
||||
@ -230,18 +230,18 @@ nsSVGDisplayContainerFrame::GetCoveredRegion()
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGDisplayContainerFrame::UpdateBounds()
|
||||
nsSVGDisplayContainerFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
NS_ABORT_IF_FALSE(GetType() != nsGkAtoms::svgOuterSVGFrame,
|
||||
"Do not call on outer-<svg>");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ nsSVGDisplayContainerFrame::UpdateBounds()
|
||||
if (SVGFrame) {
|
||||
NS_ABORT_IF_FALSE(!(kid->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"Check for this explicitly in the |if|, then");
|
||||
SVGFrame->UpdateBounds();
|
||||
SVGFrame->ReflowSVG();
|
||||
|
||||
// We build up our child frame overflows here instead of using
|
||||
// nsLayoutUtils::UnionChildOverflow since SVG frame's all use the same
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
const nsIntRect *aDirtyRect);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
NS_IMETHOD_(nsRect) GetCoveredRegion();
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
PRUint32 aFlags);
|
||||
|
@ -277,7 +277,7 @@ nsSVGMarkerProperty::DoUpdate()
|
||||
if (!(mFrame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
|
||||
// XXXjwatt: We need to unify SVG into standard reflow so we can just use
|
||||
// nsChangeHint_ReflowFrame here.
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(mFrame);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
||||
}
|
||||
mFramePresShell->FrameConstructor()->PostRestyleEvent(
|
||||
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
|
||||
|
@ -97,7 +97,7 @@ nsSVGForeignObjectFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
// XXXjwatt: why mark intrinsic widths dirty? can't we just use eResize?
|
||||
RequestReflow(nsIPresShell::eStyleChange);
|
||||
} else if (aAttribute == nsGkAtoms::x ||
|
||||
@ -105,7 +105,7 @@ nsSVGForeignObjectFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::transform) {
|
||||
// make sure our cached transform matrix gets (lazily) updated
|
||||
mCanvasTM = nsnull;
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
} else if (aAttribute == nsGkAtoms::viewBox ||
|
||||
aAttribute == nsGkAtoms::preserveAspectRatio) {
|
||||
nsSVGUtils::InvalidateBounds(this);
|
||||
@ -127,7 +127,7 @@ nsSVGForeignObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
// XXXperf: probably only need a bounds update if 'font-size' changed and
|
||||
// we have em unit width/height. Or, once we map 'transform' into style,
|
||||
// if some transform property changed.
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext,
|
||||
NS_ASSERTION(!(GetStateBits() & NS_FRAME_IS_DIRTY),
|
||||
"Reflowing while a resize is pending is wasteful");
|
||||
|
||||
// UpdateBounds makes sure mRect is up to date before we're called.
|
||||
// ReflowSVG makes sure mRect is up to date before we're called.
|
||||
|
||||
NS_ASSERTION(!aReflowState.parentReflowState,
|
||||
"should only get reflow from being reflow root");
|
||||
@ -390,15 +390,15 @@ nsSVGForeignObjectFrame::GetCoveredRegion()
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGForeignObjectFrame::UpdateBounds()
|
||||
nsSVGForeignObjectFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ nsSVGForeignObjectFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// invalidate them. We also don't need to invalidate ourself, since our
|
||||
// changed ancestor will have invalidated its entire area, which includes
|
||||
// our area.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
}
|
||||
|
||||
// If we're called while the PresShell is handling reflow events then we
|
||||
@ -593,7 +593,7 @@ nsSVGForeignObjectFrame::GetCanvasTM(PRUint32 aFor)
|
||||
void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType)
|
||||
{
|
||||
if (GetStateBits() & NS_FRAME_FIRST_REFLOW)
|
||||
// If we haven't had a UpdateBounds yet, nothing to do.
|
||||
// If we haven't had a ReflowSVG() yet, nothing to do.
|
||||
return;
|
||||
|
||||
nsIFrame* kid = GetFirstPrincipalChild();
|
||||
@ -654,7 +654,7 @@ nsSVGForeignObjectFrame::DoReflow()
|
||||
if (!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
|
||||
// Since we're a reflow root and can be reflowed independently of our
|
||||
// outer-<svg>, we can't just blindly pass 'true' here.
|
||||
FlushDirtyRegion(0, nsSVGUtils::OuterSVGIsCallingUpdateBounds(this));
|
||||
FlushDirtyRegion(0, nsSVGUtils::OuterSVGIsCallingReflowSVG(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
const nsIntRect *aDirtyRect);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
NS_IMETHOD_(nsRect) GetCoveredRegion();
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
PRUint32 aFlags);
|
||||
|
@ -95,7 +95,7 @@ nsSVGGFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::transform) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifySVGChanged(TRANSFORM_CHANGED);
|
||||
}
|
||||
|
||||
|
@ -498,13 +498,13 @@ nsSVGGlyphFrame::GetCoveredRegion()
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGGlyphFrame::UpdateBounds()
|
||||
nsSVGGlyphFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
mRect.SetEmpty();
|
||||
|
||||
@ -573,7 +573,7 @@ nsSVGGlyphFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// our area.
|
||||
// XXXjwatt: seems to me that our ancestor's change could change our glyph
|
||||
// metrics, in which case we should call NotifyGlyphMetricsChange instead.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
|
||||
if (aFlags & TRANSFORM_CHANGED) {
|
||||
ClearTextRun();
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
PRUint32 aFlags);
|
||||
|
||||
NS_IMETHOD_(nsRect) GetCoveredRegion();
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
NS_IMETHOD_(bool) IsDisplayContainer() { return false; }
|
||||
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
// nsISVGChildFrame interface:
|
||||
NS_IMETHOD PaintSVG(nsRenderingContext *aContext, const nsIntRect *aDirtyRect);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
virtual PRUint16 GetHitTestFlags();
|
||||
@ -193,7 +193,7 @@ nsSVGImageFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::y ||
|
||||
aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aAttribute == nsGkAtoms::preserveAspectRatio) {
|
||||
@ -462,15 +462,15 @@ nsSVGImageFrame::GetType() const
|
||||
// Lie about our fill/stroke so that covered region and hit detection work properly
|
||||
|
||||
void
|
||||
nsSVGImageFrame::UpdateBounds()
|
||||
nsSVGImageFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -578,7 +578,7 @@ NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest,
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(mFrame);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -605,7 +605,7 @@ NS_IMETHODIMP nsSVGImageListener::OnStartContainer(imgIRequest *aRequest,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mFrame->mImageContainer = aContainer;
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(mFrame);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(mFrame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ nsSVGInnerSVGFrame::PaintSVG(nsRenderingContext *aContext,
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGInnerSVGFrame::UpdateBounds()
|
||||
nsSVGInnerSVGFrame::ReflowSVG()
|
||||
{
|
||||
// mRect must be set before FinishAndStoreOverflow is called in order
|
||||
// for our overflow areas to be clipped correctly.
|
||||
@ -97,7 +97,7 @@ nsSVGInnerSVGFrame::UpdateBounds()
|
||||
mRect = nsLayoutUtils::RoundGfxRectToAppRect(
|
||||
gfxRect(x, y, width, height),
|
||||
PresContext()->AppUnitsPerCSSPixel());
|
||||
nsSVGInnerSVGFrameBase::UpdateBounds();
|
||||
nsSVGInnerSVGFrameBase::ReflowSVG();
|
||||
}
|
||||
|
||||
void
|
||||
@ -128,7 +128,7 @@ nsSVGInnerSVGFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// changed ancestor will have invalidated its entire area, which includes
|
||||
// our area.
|
||||
// For perf reasons we call this before calling NotifySVGChanged() below.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
}
|
||||
|
||||
// Coordinate context changes affect mCanvasTM if we have a
|
||||
@ -172,7 +172,7 @@ nsSVGInnerSVGFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
|
||||
if (aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
|
||||
if (content->HasViewBoxOrSyntheticViewBox()) {
|
||||
// make sure our cached transform matrix gets (lazily) updated
|
||||
@ -196,7 +196,7 @@ nsSVGInnerSVGFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
// make sure our cached transform matrix gets (lazily) updated
|
||||
mCanvasTM = nsnull;
|
||||
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
|
||||
nsSVGUtils::NotifyChildrenOfSVGChange(
|
||||
this, aAttribute == nsGkAtoms::viewBox ?
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
// nsISVGChildFrame interface:
|
||||
NS_IMETHOD PaintSVG(nsRenderingContext *aContext, const nsIntRect *aDirtyRect);
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
|
||||
|
@ -430,17 +430,17 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
if (!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
|
||||
// Now that we've marked the necessary children as dirty, call
|
||||
// UpdateBounds() on them:
|
||||
// ReflowSVG() on them:
|
||||
|
||||
mCallingUpdateBounds = true;
|
||||
mCallingReflowSVG = true;
|
||||
|
||||
// Update the mRects and visual overflow rects of all our descendants,
|
||||
// including our anonymous wrapper kid:
|
||||
anonKid->UpdateBounds();
|
||||
anonKid->ReflowSVG();
|
||||
NS_ABORT_IF_FALSE(!anonKid->GetNextSibling(),
|
||||
"We should have one anonymous child frame wrapping our real children");
|
||||
|
||||
mCallingUpdateBounds = false;
|
||||
mCallingReflowSVG = false;
|
||||
}
|
||||
|
||||
// Make sure we scroll if we're too big:
|
||||
|
@ -140,13 +140,13 @@ public:
|
||||
*/
|
||||
bool VerticalScrollbarNotNeeded() const;
|
||||
|
||||
bool IsCallingUpdateBounds() const {
|
||||
return mCallingUpdateBounds;
|
||||
bool IsCallingReflowSVG() const {
|
||||
return mCallingReflowSVG;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool mCallingUpdateBounds;
|
||||
bool mCallingReflowSVG;
|
||||
|
||||
/* Returns true if our content is the document element and our document is
|
||||
* embedded in an HTML 'object', 'embed' or 'applet' element. Set
|
||||
|
@ -108,7 +108,7 @@ nsSVGPathGeometryFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
(static_cast<nsSVGPathGeometryElement*>
|
||||
(mContent)->AttributeDefinesGeometry(aAttribute) ||
|
||||
aAttribute == nsGkAtoms::transform))
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -124,7 +124,7 @@ nsSVGPathGeometryFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
// style_hints don't map very well onto svg. Here seems to be the
|
||||
// best place to deal with style changes:
|
||||
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
@ -277,15 +277,15 @@ nsSVGPathGeometryFrame::GetCoveredRegion()
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPathGeometryFrame::UpdateBounds()
|
||||
nsSVGPathGeometryFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ nsSVGPathGeometryFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// invalidate them. We also don't need to invalidate ourself, since our
|
||||
// changed ancestor will have invalidated its entire area, which includes
|
||||
// our area.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
}
|
||||
|
||||
SVGBBox
|
||||
|
@ -86,7 +86,7 @@ protected:
|
||||
const nsIntRect *aDirtyRect);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
NS_IMETHOD_(nsRect) GetCoveredRegion();
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
PRUint32 aFlags);
|
||||
|
@ -606,7 +606,7 @@ nsSVGPatternFrame::GetPatternMatrix(const gfxMatrix &patternTransform,
|
||||
gfxFloat minx = bbox.X();
|
||||
gfxFloat miny = bbox.Y();
|
||||
|
||||
PRUint16 type = GetEnumValue(nsSVGPatternElement::PATTERNCONTENTUNITS);
|
||||
PRUint16 type = GetEnumValue(nsSVGPatternElement::PATTERNUNITS);
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
minx += callerBBox.X();
|
||||
miny += callerBBox.Y();
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
NS_IMETHOD PaintSVG(nsRenderingContext* aContext, const nsIntRect *aDirtyRect);
|
||||
NS_IMETHODIMP_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint);
|
||||
NS_IMETHODIMP_(nsRect) GetCoveredRegion();
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
PRUint32 aFlags);
|
||||
|
||||
@ -160,15 +160,15 @@ nsSVGSwitchFrame::GetCoveredRegion()
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGSwitchFrame::UpdateBounds()
|
||||
nsSVGSwitchFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ nsSVGSwitchFrame::UpdateBounds()
|
||||
if (svgChild) {
|
||||
NS_ABORT_IF_FALSE(!(child->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"Check for this explicitly in the |if|, then");
|
||||
svgChild->UpdateBounds();
|
||||
svgChild->ReflowSVG();
|
||||
|
||||
// We build up our child frame overflows here instead of using
|
||||
// nsLayoutUtils::UnionChildOverflow since SVG frame's all use the same
|
||||
|
@ -80,7 +80,7 @@ nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::dx ||
|
||||
aAttribute == nsGkAtoms::dy ||
|
||||
aAttribute == nsGkAtoms::rotate)) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifyGlyphMetricsChange();
|
||||
}
|
||||
|
||||
|
@ -56,14 +56,14 @@ nsSVGTextFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
return NS_OK;
|
||||
|
||||
if (aAttribute == nsGkAtoms::transform) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifySVGChanged(TRANSFORM_CHANGED);
|
||||
} else if (aAttribute == nsGkAtoms::x ||
|
||||
aAttribute == nsGkAtoms::y ||
|
||||
aAttribute == nsGkAtoms::dx ||
|
||||
aAttribute == nsGkAtoms::dy ||
|
||||
aAttribute == nsGkAtoms::rotate) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifyGlyphMetricsChange();
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ nsSVGTextFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// changed ancestor will have invalidated its entire area, which includes
|
||||
// our area.
|
||||
// For perf reasons we call this before calling NotifySVGChanged() below.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
}
|
||||
|
||||
nsSVGTextFrameBase::NotifySVGChanged(aFlags);
|
||||
@ -230,15 +230,15 @@ nsSVGTextFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTextFrame::UpdateBounds()
|
||||
nsSVGTextFrame::ReflowSVG()
|
||||
{
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingUpdateBounds(this),
|
||||
"This call is probaby a wasteful mistake");
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"UpdateBounds mechanism not designed for this");
|
||||
"ReflowSVG mechanism not designed for this");
|
||||
|
||||
if (!nsSVGUtils::NeedsUpdatedBounds(this)) {
|
||||
if (!nsSVGUtils::NeedsReflowSVG(this)) {
|
||||
NS_ASSERTION(!mPositioningDirty, "How did this happen?");
|
||||
return;
|
||||
}
|
||||
@ -261,7 +261,7 @@ nsSVGTextFrame::UpdateBounds()
|
||||
|
||||
// With glyph positions updated, our descendants can invalidate their new
|
||||
// areas correctly:
|
||||
nsSVGTextFrameBase::UpdateBounds();
|
||||
nsSVGTextFrameBase::ReflowSVG();
|
||||
|
||||
if (invalidate) {
|
||||
// XXXSDL Let FinishAndStoreOverflow do this.
|
||||
@ -334,10 +334,10 @@ void
|
||||
nsSVGTextFrame::NotifyGlyphMetricsChange()
|
||||
{
|
||||
// NotifySVGChanged isn't appropriate here, so we just mark our descendants
|
||||
// as fully dirty to get UpdateBounds() called on them:
|
||||
// as fully dirty to get ReflowSVG() called on them:
|
||||
MarkDirtyBitsOnDescendants(this);
|
||||
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
|
||||
mPositioningDirty = true;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
NS_IMETHOD PaintSVG(nsRenderingContext* aContext,
|
||||
const nsIntRect *aDirtyRect);
|
||||
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint & aPoint);
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
PRUint32 aFlags);
|
||||
|
||||
|
@ -157,11 +157,11 @@ nsSVGTextPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::startOffset) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
NotifyGlyphMetricsChange();
|
||||
} else if (aNameSpaceID == kNameSpaceID_XLink &&
|
||||
aAttribute == nsGkAtoms::href) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
// Blow away our reference, if any
|
||||
Properties().Delete(nsSVGEffects::HrefProperty());
|
||||
NotifyGlyphMetricsChange();
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
#endif
|
||||
|
||||
// nsISVGChildFrame interface:
|
||||
virtual void UpdateBounds();
|
||||
virtual void ReflowSVG();
|
||||
virtual void NotifySVGChanged(PRUint32 aFlags);
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
@ -123,7 +123,7 @@ nsSVGUseFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::y) {
|
||||
// make sure our cached transform matrix gets (lazily) updated
|
||||
mCanvasTM = nsnull;
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
|
||||
} else if (aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height) {
|
||||
@ -137,13 +137,13 @@ nsSVGUseFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
useElement->SyncWidthOrHeight(aAttribute);
|
||||
}
|
||||
if (invalidate) {
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
}
|
||||
}
|
||||
} else if (aNameSpaceID == kNameSpaceID_XLink &&
|
||||
aAttribute == nsGkAtoms::href) {
|
||||
// we're changing our nature, clear out the clone information
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
|
||||
useElement->mOriginal = nsnull;
|
||||
useElement->UnlinkSource();
|
||||
useElement->TriggerReclone();
|
||||
@ -172,7 +172,7 @@ nsSVGUseFrame::IsLeaf() const
|
||||
// nsISVGChildFrame methods
|
||||
|
||||
void
|
||||
nsSVGUseFrame::UpdateBounds()
|
||||
nsSVGUseFrame::ReflowSVG()
|
||||
{
|
||||
// We only handle x/y offset here, since any width/height that is in force is
|
||||
// handled by the nsSVGOuterSVGFrame for the anonymous <svg> that will be
|
||||
@ -183,7 +183,7 @@ nsSVGUseFrame::UpdateBounds()
|
||||
mRect.MoveTo(nsLayoutUtils::RoundGfxRectToAppRect(
|
||||
gfxRect(x, y, 0.0, 0.0),
|
||||
PresContext()->AppUnitsPerCSSPixel()).TopLeft());
|
||||
nsSVGUseFrameBase::UpdateBounds();
|
||||
nsSVGUseFrameBase::ReflowSVG();
|
||||
}
|
||||
|
||||
void
|
||||
@ -203,7 +203,7 @@ nsSVGUseFrame::NotifySVGChanged(PRUint32 aFlags)
|
||||
// changed ancestor will have invalidated its entire area, which includes
|
||||
// our area.
|
||||
// For perf reasons we call this before calling NotifySVGChanged() below.
|
||||
nsSVGUtils::ScheduleBoundsUpdate(this);
|
||||
nsSVGUtils::ScheduleReflowSVG(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,9 +595,9 @@ nsSVGUtils::GetPostFilterVisualOverflowRect(nsIFrame *aFrame,
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGUtils::OuterSVGIsCallingUpdateBounds(nsIFrame *aFrame)
|
||||
nsSVGUtils::OuterSVGIsCallingReflowSVG(nsIFrame *aFrame)
|
||||
{
|
||||
return nsSVGUtils::GetOuterSVGFrame(aFrame)->IsCallingUpdateBounds();
|
||||
return nsSVGUtils::GetOuterSVGFrame(aFrame)->IsCallingReflowSVG();
|
||||
}
|
||||
|
||||
void
|
||||
@ -608,20 +608,20 @@ nsSVGUtils::InvalidateBounds(nsIFrame *aFrame, bool aDuringUpdate,
|
||||
!(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG),
|
||||
"Passed bad frame!");
|
||||
|
||||
NS_ASSERTION(aDuringUpdate == OuterSVGIsCallingUpdateBounds(aFrame),
|
||||
NS_ASSERTION(aDuringUpdate == OuterSVGIsCallingReflowSVG(aFrame),
|
||||
"aDuringUpdate lies!");
|
||||
|
||||
// Rendering observers must be notified about changes to the frames that they
|
||||
// are observing _before_ UpdateBounds is called on the SVG frame tree, so we
|
||||
// only need to notify observers if we're not under an UpdateBounds call.
|
||||
// are observing _before_ ReflowSVG is called on the SVG frame tree, so we
|
||||
// only need to notify observers if we're not under an ReflowSVG call.
|
||||
// In fact, it would actually be wrong to notify observers while under
|
||||
// UpdateBounds because the observers will try to mark themselves as dirty
|
||||
// and, since UpdateBounds would be in the process of _removeing_ dirty bits
|
||||
// ReflowSVG because the observers will try to mark themselves as dirty
|
||||
// and, since ReflowSVG would be in the process of _removeing_ dirty bits
|
||||
// from frames, that would mess things up.
|
||||
if (!aDuringUpdate) {
|
||||
NS_ASSERTION(!OuterSVGIsCallingUpdateBounds(aFrame),
|
||||
NS_ASSERTION(!OuterSVGIsCallingReflowSVG(aFrame),
|
||||
"Must not InvalidateRenderingObservers() under "
|
||||
"nsISVGChildFrame::UpdateBounds!");
|
||||
"nsISVGChildFrame::ReflowSVG!");
|
||||
|
||||
nsSVGEffects::InvalidateRenderingObservers(aFrame);
|
||||
}
|
||||
@ -708,16 +708,16 @@ nsSVGUtils::InvalidateBounds(nsIFrame *aFrame, bool aDuringUpdate,
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::ScheduleBoundsUpdate(nsIFrame *aFrame)
|
||||
nsSVGUtils::ScheduleReflowSVG(nsIFrame *aFrame)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFrame->IsFrameOfType(nsIFrame::eSVG),
|
||||
"Passed bad frame!");
|
||||
|
||||
// If this is triggered, the callers should be fixed to call us before
|
||||
// UpdateBounds is called. If we try to mark dirty bits on frames while we're
|
||||
// ReflowSVG is called. If we try to mark dirty bits on frames while we're
|
||||
// in the process of removing them, things will get messed up.
|
||||
NS_ASSERTION(!OuterSVGIsCallingUpdateBounds(aFrame),
|
||||
"Do not call under nsISVGChildFrame::UpdateBounds!");
|
||||
NS_ASSERTION(!OuterSVGIsCallingReflowSVG(aFrame),
|
||||
"Do not call under nsISVGChildFrame::ReflowSVG!");
|
||||
|
||||
// We don't call nsSVGEffects::InvalidateRenderingObservers here because
|
||||
// we should only be called under InvalidateAndScheduleBoundsUpdate (which
|
||||
@ -778,20 +778,20 @@ nsSVGUtils::ScheduleBoundsUpdate(nsIFrame *aFrame)
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(nsIFrame *aFrame)
|
||||
nsSVGUtils::InvalidateAndScheduleReflowSVG(nsIFrame *aFrame)
|
||||
{
|
||||
// If this is triggered, the callers should be fixed to call us much
|
||||
// earlier. If we try to mark dirty bits on frames while we're in the
|
||||
// process of removing them, things will get messed up.
|
||||
NS_ASSERTION(!OuterSVGIsCallingUpdateBounds(aFrame),
|
||||
"Must not call under nsISVGChildFrame::UpdateBounds!");
|
||||
NS_ASSERTION(!OuterSVGIsCallingReflowSVG(aFrame),
|
||||
"Must not call under nsISVGChildFrame::ReflowSVG!");
|
||||
|
||||
InvalidateBounds(aFrame, false);
|
||||
ScheduleBoundsUpdate(aFrame);
|
||||
ScheduleReflowSVG(aFrame);
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGUtils::NeedsUpdatedBounds(nsIFrame *aFrame)
|
||||
nsSVGUtils::NeedsReflowSVG(nsIFrame *aFrame)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFrame->IsFrameOfType(nsIFrame::eSVG),
|
||||
"SVG uses bits differently!");
|
||||
|
@ -347,8 +347,8 @@ public:
|
||||
* the new area that the frame should paint to).
|
||||
*
|
||||
* This does nothing when passed an NS_STATE_SVG_NONDISPLAY_CHILD frame.
|
||||
* In future we may want to allow UpdateBounds to be called on such frames,
|
||||
* but that would be better implemented as a ForceUpdateBounds function to
|
||||
* In future we may want to allow ReflowSVG to be called on such frames,
|
||||
* but that would be better implemented as a ForceReflowSVG function to
|
||||
* be called synchronously while painting them without marking or paying
|
||||
* attention to dirty bits like this function.
|
||||
*
|
||||
@ -370,20 +370,20 @@ public:
|
||||
* handle nsSVGForeignObjectFrame specially. It would also do unnecessary work
|
||||
* descending into NS_STATE_SVG_NONDISPLAY_CHILD frames.
|
||||
*/
|
||||
static void ScheduleBoundsUpdate(nsIFrame *aFrame);
|
||||
static void ScheduleReflowSVG(nsIFrame *aFrame);
|
||||
|
||||
/**
|
||||
* Invalidates the area that the frame last painted to, then schedules an
|
||||
* update of the frame's bounds (which will in turn invalidate the new area
|
||||
* that the frame should paint to).
|
||||
*/
|
||||
static void InvalidateAndScheduleBoundsUpdate(nsIFrame *aFrame);
|
||||
static void InvalidateAndScheduleReflowSVG(nsIFrame *aFrame);
|
||||
|
||||
/**
|
||||
* Returns true if the frame or any of its children need UpdateBounds
|
||||
* Returns true if the frame or any of its children need ReflowSVG
|
||||
* to be called on them.
|
||||
*/
|
||||
static bool NeedsUpdatedBounds(nsIFrame *aFrame);
|
||||
static bool NeedsReflowSVG(nsIFrame *aFrame);
|
||||
|
||||
/*
|
||||
* Update the filter invalidation region for ancestor frames, if relevant.
|
||||
@ -630,7 +630,7 @@ public:
|
||||
WritePPM(const char *fname, gfxImageSurface *aSurface);
|
||||
#endif
|
||||
|
||||
static bool OuterSVGIsCallingUpdateBounds(nsIFrame *aFrame);
|
||||
static bool OuterSVGIsCallingReflowSVG(nsIFrame *aFrame);
|
||||
|
||||
/*
|
||||
* Get any additional transforms that apply only to stroking
|
||||
|
@ -12,6 +12,7 @@ import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PluginLayer;
|
||||
import org.mozilla.gecko.gfx.PointUtils;
|
||||
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
|
||||
import org.mozilla.gecko.ui.PanZoomController;
|
||||
|
||||
import java.io.*;
|
||||
@ -234,6 +235,14 @@ abstract public class GeckoApp
|
||||
}
|
||||
}
|
||||
|
||||
// we don't support Honeycomb
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB &&
|
||||
Build.VERSION.SDK_INT < 14 /*Build.VERSION_CODES.ICE_CREAM_SANDWICH*/ )
|
||||
{
|
||||
Log.w(LOGTAG, "Blocking plugins because of Honeycomb");
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start of getPluginDirectories");
|
||||
|
||||
ArrayList<String> directories = new ArrayList<String>();
|
||||
@ -1603,6 +1612,51 @@ abstract public class GeckoApp
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Surface createSurface() {
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
if (tab == null)
|
||||
return null;
|
||||
|
||||
SurfaceTextureLayer layer = SurfaceTextureLayer.create();
|
||||
if (layer == null)
|
||||
return null;
|
||||
|
||||
Surface surface = layer.getSurface();
|
||||
tab.addPluginLayer(surface, layer);
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void destroySurface(Surface surface) {
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
Layer layer = tab.removePluginLayer(surface);
|
||||
hidePluginLayer(layer);
|
||||
}
|
||||
|
||||
public void showSurface(Surface surface, int x, int y,
|
||||
int w, int h, boolean inverted, boolean blend) {
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
LayerView layerView = mLayerController.getView();
|
||||
SurfaceTextureLayer layer = (SurfaceTextureLayer)tab.getPluginLayer(surface);
|
||||
if (layer == null)
|
||||
return;
|
||||
|
||||
layer.update(new Rect(x, y, x + w, y + h), inverted, blend);
|
||||
layerView.addLayer(layer);
|
||||
|
||||
// FIXME: shouldn't be necessary, layer will request
|
||||
// one when it gets first frame
|
||||
layerView.requestRender();
|
||||
}
|
||||
|
||||
private void hidePluginLayer(Layer layer) {
|
||||
LayerView layerView = mLayerController.getView();
|
||||
@ -1616,6 +1670,19 @@ abstract public class GeckoApp
|
||||
layerView.requestRender();
|
||||
}
|
||||
|
||||
public void hideSurface(Surface surface) {
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
Layer layer = tab.getPluginLayer(surface);
|
||||
if (layer == null)
|
||||
return;
|
||||
|
||||
hidePluginLayer(layer);
|
||||
}
|
||||
|
||||
public void requestRender() {
|
||||
mLayerController.getView().requestRender();
|
||||
}
|
||||
|
@ -145,7 +145,6 @@ public class GeckoAppShell
|
||||
public static native void loadNSSLibsNative(String apkName, boolean shouldExtract);
|
||||
public static native void onChangeNetworkLinkStatus(String status);
|
||||
public static native Message getNextMessageFromQueue(MessageQueue queue);
|
||||
public static native void onSurfaceTextureFrameAvailable(SurfaceTexture surfaceTexture, int id);
|
||||
|
||||
public static void registerGlobalExceptionHandler() {
|
||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@ -1691,6 +1690,35 @@ public class GeckoAppShell
|
||||
GeckoApp.mAppContext.removePluginView(view, isFullScreen);
|
||||
}
|
||||
|
||||
public static Surface createSurface() {
|
||||
Log.i(LOGTAG, "createSurface");
|
||||
return GeckoApp.mAppContext.createSurface();
|
||||
}
|
||||
|
||||
public static void showSurface(Surface surface,
|
||||
int x, int y,
|
||||
int w, int h,
|
||||
boolean inverted,
|
||||
boolean blend)
|
||||
{
|
||||
Log.i(LOGTAG, "showSurface:" + surface + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h + " inverted: " + inverted + " blend: " + blend);
|
||||
try {
|
||||
GeckoApp.mAppContext.showSurface(surface, x, y, w, h, inverted, blend);
|
||||
} catch (Exception e) {
|
||||
Log.i(LOGTAG, "Error in showSurface:", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hideSurface(Surface surface) {
|
||||
Log.i(LOGTAG, "hideSurface:" + surface);
|
||||
GeckoApp.mAppContext.hideSurface(surface);
|
||||
}
|
||||
|
||||
public static void destroySurface(Surface surface) {
|
||||
Log.i(LOGTAG, "destroySurface:" + surface);
|
||||
GeckoApp.mAppContext.destroySurface(surface);
|
||||
}
|
||||
|
||||
public static Class<?> loadPluginClass(String className, String libName) {
|
||||
Log.i(LOGTAG, "in loadPluginClass... attempting to access className, then libName.....");
|
||||
Log.i(LOGTAG, "className: " + className);
|
||||
@ -2256,17 +2284,6 @@ public class GeckoAppShell
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void registerSurfaceTextureFrameListener(SurfaceTexture surfaceTexture, final int id) {
|
||||
surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
|
||||
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
|
||||
GeckoAppShell.onSurfaceTextureFrameAvailable(surfaceTexture, id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void unregisterSurfaceTextureFrameListener(SurfaceTexture surfaceTexture) {
|
||||
surfaceTexture.setOnFrameAvailableListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
class ScreenshotHandler implements Runnable {
|
||||
|
@ -137,6 +137,7 @@ FENNEC_JAVA_FILES = \
|
||||
gfx/ScreenshotLayer.java \
|
||||
gfx/ScrollbarLayer.java \
|
||||
gfx/SingleTileLayer.java \
|
||||
gfx/SurfaceTextureLayer.java \
|
||||
gfx/TextLayer.java \
|
||||
gfx/TextureGenerator.java \
|
||||
gfx/TextureReaper.java \
|
||||
|
279
mobile/android/base/gfx/SurfaceTextureLayer.java
Normal file
279
mobile/android/base/gfx/SurfaceTextureLayer.java
Normal file
@ -0,0 +1,279 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.GLES20;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class SurfaceTextureLayer extends Layer implements SurfaceTexture.OnFrameAvailableListener {
|
||||
private static final String LOGTAG = "SurfaceTextureLayer";
|
||||
private static final int LOCAL_GL_TEXTURE_EXTERNAL_OES = 0x00008d65; // This is only defined in API level 15 for some reason (Android 4.0.3)
|
||||
|
||||
private final SurfaceTexture mSurfaceTexture;
|
||||
private final Surface mSurface;
|
||||
private int mTextureId;
|
||||
private boolean mHaveFrame;
|
||||
private float[] mTextureTransform = new float[16];
|
||||
|
||||
private Rect mPageRect;
|
||||
|
||||
private boolean mInverted;
|
||||
private boolean mNewInverted;
|
||||
private boolean mBlend;
|
||||
private boolean mNewBlend;
|
||||
|
||||
private static int mProgram;
|
||||
private static int mPositionHandle;
|
||||
private static int mTextureHandle;
|
||||
private static int mSampleHandle;
|
||||
private static int mProjectionMatrixHandle;
|
||||
private static int mTextureMatrixHandle;
|
||||
|
||||
private static final float[] PROJECTION_MATRIX = {
|
||||
2.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 2.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
private static final String VERTEX_SHADER =
|
||||
"uniform mat4 projectionMatrix;\n" +
|
||||
"uniform mat4 textureMatrix;\n" +
|
||||
"attribute vec4 vPosition;\n" +
|
||||
"attribute vec4 aTexCoord;\n" +
|
||||
"varying vec2 vTexCoord;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_Position = projectionMatrix * vPosition;\n" +
|
||||
" vTexCoord = (textureMatrix * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;\n" +
|
||||
"}\n";
|
||||
|
||||
private static String FRAGMENT_SHADER_OES =
|
||||
"#extension GL_OES_EGL_image_external : require\n" +
|
||||
"precision mediump float;\n" +
|
||||
"varying vec2 vTexCoord; \n" +
|
||||
"uniform samplerExternalOES sTexture; \n" +
|
||||
"void main() {\n" +
|
||||
" gl_FragColor = texture2D(sTexture, vTexCoord); \n" +
|
||||
"}\n";
|
||||
|
||||
|
||||
private static final float TEXTURE_MAP[] = {
|
||||
0.0f, 1.0f, // top left
|
||||
0.0f, 0.0f, // bottom left
|
||||
1.0f, 1.0f, // top right
|
||||
1.0f, 0.0f, // bottom right
|
||||
};
|
||||
|
||||
private static final float TEXTURE_MAP_INVERTED[] = {
|
||||
0.0f, 0.0f, // bottom left
|
||||
0.0f, 1.0f, // top left
|
||||
1.0f, 0.0f, // bottom right
|
||||
1.0f, 1.0f, // top right
|
||||
};
|
||||
|
||||
private SurfaceTextureLayer(int textureId) {
|
||||
mTextureId = textureId;
|
||||
mHaveFrame = true;
|
||||
mInverted = false;
|
||||
|
||||
// We have our own special shaders necessary for rendering the SurfaceTexture
|
||||
this.mUsesDefaultProgram = false;
|
||||
|
||||
mSurfaceTexture = new SurfaceTexture(mTextureId);
|
||||
mSurfaceTexture.setOnFrameAvailableListener(this);
|
||||
|
||||
Surface tmp = null;
|
||||
try {
|
||||
tmp = Surface.class.getConstructor(SurfaceTexture.class).newInstance(mSurfaceTexture); }
|
||||
catch (Exception ie) {
|
||||
Log.e(LOGTAG, "error constructing the surface", ie);
|
||||
}
|
||||
|
||||
mSurface = tmp;
|
||||
}
|
||||
|
||||
public static SurfaceTextureLayer create() {
|
||||
int textureId = TextureGenerator.get().take();
|
||||
if (textureId == 0)
|
||||
return null;
|
||||
|
||||
return new SurfaceTextureLayer(textureId);
|
||||
}
|
||||
|
||||
// For SurfaceTexture.OnFrameAvailableListener
|
||||
public void onFrameAvailable(SurfaceTexture texture) {
|
||||
mHaveFrame = true;
|
||||
GeckoApp.mAppContext.requestRender();
|
||||
}
|
||||
|
||||
public void update(Rect rect, boolean inverted, boolean blend) {
|
||||
beginTransaction();
|
||||
|
||||
setPosition(rect);
|
||||
|
||||
mNewInverted = inverted;
|
||||
mNewBlend = blend;
|
||||
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (mTextureId > 0)
|
||||
TextureReaper.get().add(mTextureId);
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performUpdates(RenderContext context) {
|
||||
super.performUpdates(context);
|
||||
|
||||
mInverted = mNewInverted;
|
||||
mBlend = mNewBlend;
|
||||
}
|
||||
|
||||
private static boolean ensureProgram() {
|
||||
if (mProgram != 0)
|
||||
return true;
|
||||
|
||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER);
|
||||
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_OES);
|
||||
|
||||
mProgram = GLES20.glCreateProgram();
|
||||
GLES20.glAttachShader(mProgram, vertexShader);
|
||||
GLES20.glAttachShader(mProgram, fragmentShader);
|
||||
GLES20.glLinkProgram(mProgram);
|
||||
|
||||
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
|
||||
mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord");
|
||||
mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
|
||||
mProjectionMatrixHandle = GLES20.glGetUniformLocation(mProgram, "projectionMatrix");
|
||||
mTextureMatrixHandle = GLES20.glGetUniformLocation(mProgram, "textureMatrix");
|
||||
|
||||
return mProgram != 0;
|
||||
}
|
||||
|
||||
private static int loadShader(int type, String shaderCode) {
|
||||
int shader = GLES20.glCreateShader(type);
|
||||
GLES20.glShaderSource(shader, shaderCode);
|
||||
GLES20.glCompileShader(shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
private static void activateProgram() {
|
||||
GLES20.glUseProgram(mProgram);
|
||||
}
|
||||
|
||||
public static void deactivateProgram() {
|
||||
GLES20.glDisableVertexAttribArray(mTextureHandle);
|
||||
GLES20.glDisableVertexAttribArray(mPositionHandle);
|
||||
GLES20.glUseProgram(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(RenderContext context) {
|
||||
if (!ensureProgram() || !mHaveFrame)
|
||||
return;
|
||||
|
||||
RectF rect = getBounds(context);
|
||||
RectF viewport = context.viewport;
|
||||
rect.offset(-viewport.left, -viewport.top);
|
||||
|
||||
float viewWidth = viewport.width();
|
||||
float viewHeight = viewport.height();
|
||||
|
||||
float top = viewHeight - rect.top;
|
||||
float bot = viewHeight - rect.bottom;
|
||||
|
||||
float[] textureCoords = mInverted ? TEXTURE_MAP_INVERTED : TEXTURE_MAP;
|
||||
|
||||
float[] coords = {
|
||||
// x, y, z, texture_x, texture_y
|
||||
rect.left/viewWidth, bot/viewHeight, 0,
|
||||
textureCoords[0], textureCoords[1],
|
||||
|
||||
rect.left/viewWidth, (bot+rect.height())/viewHeight, 0,
|
||||
textureCoords[2], textureCoords[3],
|
||||
|
||||
(rect.left+rect.width())/viewWidth, bot/viewHeight, 0,
|
||||
textureCoords[4], textureCoords[5],
|
||||
|
||||
(rect.left+rect.width())/viewWidth, (bot+rect.height())/viewHeight, 0,
|
||||
textureCoords[6], textureCoords[7]
|
||||
};
|
||||
|
||||
FloatBuffer coordBuffer = context.coordBuffer;
|
||||
coordBuffer.position(0);
|
||||
coordBuffer.put(coords);
|
||||
|
||||
activateProgram();
|
||||
|
||||
// Set the transformation matrix
|
||||
GLES20.glUniformMatrix4fv(mProjectionMatrixHandle, 1, false, PROJECTION_MATRIX, 0);
|
||||
|
||||
// Enable the arrays from which we get the vertex and texture coordinates
|
||||
GLES20.glEnableVertexAttribArray(mPositionHandle);
|
||||
GLES20.glEnableVertexAttribArray(mTextureHandle);
|
||||
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glUniform1i(mSampleHandle, 0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
GLES20.glBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mTextureId);
|
||||
|
||||
mSurfaceTexture.updateTexImage();
|
||||
mSurfaceTexture.getTransformMatrix(mTextureTransform);
|
||||
|
||||
GLES20.glUniformMatrix4fv(mTextureMatrixHandle, 1, false, mTextureTransform, 0);
|
||||
|
||||
// Unbind any the current array buffer so we can use client side buffers
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Vertex coordinates are x,y,z starting at position 0 into the buffer.
|
||||
coordBuffer.position(0);
|
||||
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 20,
|
||||
coordBuffer);
|
||||
|
||||
// Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
|
||||
coordBuffer.position(3);
|
||||
GLES20.glVertexAttribPointer(mTextureHandle, 2, GLES20.GL_FLOAT, false, 20,
|
||||
coordBuffer);
|
||||
|
||||
if (mBlend) {
|
||||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
if (mBlend)
|
||||
GLES20.glDisable(GLES20.GL_BLEND);
|
||||
|
||||
deactivateProgram();
|
||||
}
|
||||
|
||||
public SurfaceTexture getSurfaceTexture() {
|
||||
return mSurfaceTexture;
|
||||
}
|
||||
|
||||
public Surface getSurface() {
|
||||
return mSurface;
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +323,6 @@ SHELL_WRAPPER2(notifyFilePickerResult, jstring, jlong)
|
||||
SHELL_WRAPPER1_WITH_RETURN(getSurfaceBits, jobject, jobject)
|
||||
SHELL_WRAPPER1(onFullScreenPluginHidden, jobject)
|
||||
SHELL_WRAPPER1_WITH_RETURN(getNextMessageFromQueue, jobject, jobject)
|
||||
SHELL_WRAPPER2(onSurfaceTextureFrameAvailable, jobject, jint);
|
||||
|
||||
static void * xul_handle = NULL;
|
||||
static void * sqlite_handle = NULL;
|
||||
@ -747,7 +746,6 @@ loadGeckoLibs(const char *apkName)
|
||||
GETFUNC(getSurfaceBits);
|
||||
GETFUNC(onFullScreenPluginHidden);
|
||||
GETFUNC(getNextMessageFromQueue);
|
||||
GETFUNC(onSurfaceTextureFrameAvailable);
|
||||
#undef GETFUNC
|
||||
|
||||
void (*XRE_StartupTimelineRecord)(int, MOZTime);
|
||||
|
@ -243,7 +243,7 @@ function makeHiddenFrame() {
|
||||
// TODO: disable media (bug 759964)
|
||||
|
||||
// Mark this docShell as a "browserFrame", to break script access to e.g. window.top
|
||||
docShell.setIsBrowser();
|
||||
docShell.setIsBrowserElement();
|
||||
|
||||
return iframe;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ Sandbox.prototype = {
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
|
||||
// Mark this docShell as a "browserFrame", to break script access to e.g. window.top
|
||||
docShell.setIsBrowser();
|
||||
docShell.setIsBrowserElement();
|
||||
|
||||
// Stop about:blank from being loaded.
|
||||
docShell.stop(Ci.nsIWebNavigation.STOP_NETWORK);
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsIDOMClientRect.h"
|
||||
#include "StrongPointer.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ALOG_BRIDGE(args...) ALOG(args)
|
||||
@ -50,15 +49,6 @@ AndroidBridge *AndroidBridge::sBridge = 0;
|
||||
static PRUintn sJavaEnvThreadIndex = 0;
|
||||
static void JavaThreadDetachFunc(void *arg);
|
||||
|
||||
// This is a dummy class that can be used in the template for android::sp
|
||||
class AndroidRefable {
|
||||
void incStrong(void* thing) { }
|
||||
void decStrong(void* thing) { }
|
||||
};
|
||||
|
||||
// This isn't in AndroidBridge.h because including StrongPointer.h there is gross
|
||||
static android::sp<AndroidRefable> (*android_SurfaceTexture_getNativeWindow)(JNIEnv* env, jobject surfaceTexture) = nsnull;
|
||||
|
||||
AndroidBridge *
|
||||
AndroidBridge::ConstructBridge(JNIEnv *jEnv,
|
||||
jclass jGeckoAppShellClass)
|
||||
@ -188,10 +178,11 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
|
||||
jSurfaceClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("android/view/Surface"));
|
||||
|
||||
if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv))
|
||||
PRInt32 apiVersion = 0;
|
||||
if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &apiVersion, jEnv))
|
||||
ALOG_BRIDGE("Failed to find API version");
|
||||
|
||||
if (mAPIVersion <= 8 /* Froyo */)
|
||||
if (apiVersion <= 8 /* Froyo */)
|
||||
jSurfacePointerField = jEnv->GetFieldID(jSurfaceClass, "mSurface", "I");
|
||||
else /* not Froyo */
|
||||
jSurfacePointerField = jEnv->GetFieldID(jSurfaceClass, "mNativeSurface", "I");
|
||||
@ -199,8 +190,6 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
jNotifyWakeLockChanged = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
|
||||
jGetGfxInfoData = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getGfxInfoData", "()Ljava/lang/String;");
|
||||
jRegisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "registerSurfaceTextureFrameListener", "(Landroid/graphics/SurfaceTexture;I)V");
|
||||
jUnregisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "unregisterSurfaceTextureFrameListener", "(Landroid/graphics/SurfaceTexture;)V");
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
jPumpMessageLoop = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "pumpMessageLoop", "()V");
|
||||
@ -208,6 +197,11 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;IIIIZ)V");
|
||||
jRemovePluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "removePluginView", "(Landroid/view/View;Z)V");
|
||||
|
||||
jCreateSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "createSurface", "()Landroid/view/Surface;");
|
||||
jShowSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "showSurface", "(Landroid/view/Surface;IIIIZZ)V");
|
||||
jHideSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideSurface", "(Landroid/view/Surface;)V");
|
||||
jDestroySurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "destroySurface", "(Landroid/view/Surface;)V");
|
||||
|
||||
jLayerView = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("org/mozilla/gecko/gfx/LayerView"));
|
||||
|
||||
AndroidGLController::Init(jEnv);
|
||||
@ -1402,20 +1396,11 @@ AndroidBridge::OpenGraphicsLibraries()
|
||||
ANativeWindow_lock = (int (*)(void*, void*, void*)) dlsym(handle, "ANativeWindow_lock");
|
||||
ANativeWindow_unlockAndPost = (int (*)(void*))dlsym(handle, "ANativeWindow_unlockAndPost");
|
||||
|
||||
// This is only available in Honeycomb and ICS. It was removed in Jelly Bean
|
||||
ANativeWindow_fromSurfaceTexture = (void* (*)(JNIEnv*, jobject))dlsym(handle, "ANativeWindow_fromSurfaceTexture");
|
||||
|
||||
mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release && ANativeWindow_lock && ANativeWindow_unlockAndPost;
|
||||
|
||||
ALOG_BRIDGE("Successfully opened libandroid.so, have native window access? %d", mHasNativeWindowAccess);
|
||||
}
|
||||
|
||||
// We need one symbol from here on Jelly Bean
|
||||
handle = dlopen("libandroid_runtime.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (handle) {
|
||||
android_SurfaceTexture_getNativeWindow = (android::sp<AndroidRefable> (*)(JNIEnv*, jobject))dlsym(handle, "_ZN7android38android_SurfaceTexture_getNativeWindowEP7_JNIEnvP8_jobject");
|
||||
}
|
||||
|
||||
if (mHasNativeWindowAccess)
|
||||
return;
|
||||
|
||||
@ -1954,11 +1939,10 @@ AndroidBridge::AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface)
|
||||
|
||||
if (mHasNativeWindowAccess)
|
||||
return ANativeWindow_fromSurface(aEnv, aSurface);
|
||||
|
||||
if (mHasNativeWindowFallback)
|
||||
else if (mHasNativeWindowFallback)
|
||||
return GetNativeSurface(aEnv, aSurface);
|
||||
|
||||
return nsnull;
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1974,31 +1958,6 @@ AndroidBridge::ReleaseNativeWindow(void *window)
|
||||
// have nothing to do here. We should probably ref it.
|
||||
}
|
||||
|
||||
void*
|
||||
AndroidBridge::AcquireNativeWindowFromSurfaceTexture(JNIEnv* aEnv, jobject aSurfaceTexture)
|
||||
{
|
||||
OpenGraphicsLibraries();
|
||||
|
||||
if (mHasNativeWindowAccess && ANativeWindow_fromSurfaceTexture)
|
||||
return ANativeWindow_fromSurfaceTexture(aEnv, aSurfaceTexture);
|
||||
|
||||
if (mHasNativeWindowAccess && android_SurfaceTexture_getNativeWindow) {
|
||||
android::sp<AndroidRefable> window = android_SurfaceTexture_getNativeWindow(aEnv, aSurfaceTexture);
|
||||
return window.get();
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::ReleaseNativeWindowForSurfaceTexture(void *window)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
// FIXME: we don't ref the pointer we get, so nothing to do currently. We should ref it.
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::SetNativeWindowFormat(void *window, int width, int height, int format)
|
||||
{
|
||||
@ -2231,6 +2190,75 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
jobject
|
||||
AndroidBridge::CreateSurface()
|
||||
{
|
||||
#ifndef MOZ_JAVA_COMPOSITOR
|
||||
return NULL;
|
||||
#else
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return nsnull;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
jobject surface = env->CallStaticObjectMethod(mGeckoAppShellClass, jCreateSurface);
|
||||
if (jniFrame.CheckForException())
|
||||
return nsnull;
|
||||
|
||||
if (surface)
|
||||
surface = env->NewGlobalRef(surface);
|
||||
|
||||
return surface;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::DestroySurface(jobject surface)
|
||||
{
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jDestroySurface, surface);
|
||||
env->DeleteGlobalRef(surface);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend)
|
||||
{
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jShowSurface, surface,
|
||||
(int)aRect.x, (int)aRect.y,
|
||||
(int)aRect.width, (int)aRect.height,
|
||||
aInverted, aBlend);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::HideSurface(jobject surface)
|
||||
{
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jHideSurface, surface);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AndroidBridge::GetScreenOrientation()
|
||||
{
|
||||
@ -2330,38 +2358,6 @@ AndroidBridge::NotifyWakeLockChanged(const nsAString& topic, const nsAString& st
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyWakeLockChanged, jstrTopic, jstrState);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::ScheduleComposite()
|
||||
{
|
||||
#if MOZ_JAVA_COMPOSITOR
|
||||
nsWindow::ScheduleComposite();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::RegisterSurfaceTextureFrameListener(jobject surfaceTexture, int id)
|
||||
{
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jRegisterSurfaceTextureFrameListener, surfaceTexture, id);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::UnregisterSurfaceTextureFrameListener(jobject surfaceTexture)
|
||||
{
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jUnregisterSurfaceTextureFrameListener, surfaceTexture);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::GetGfxInfoData(nsACString& aRet)
|
||||
{
|
||||
|
@ -297,10 +297,6 @@ public:
|
||||
|
||||
void *AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface);
|
||||
void ReleaseNativeWindow(void *window);
|
||||
|
||||
void *AcquireNativeWindowFromSurfaceTexture(JNIEnv* aEnv, jobject aSurface);
|
||||
void ReleaseNativeWindowForSurfaceTexture(void *window);
|
||||
|
||||
bool SetNativeWindowFormat(void *window, int width, int height, int format);
|
||||
|
||||
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
|
||||
@ -339,6 +335,11 @@ public:
|
||||
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
|
||||
|
||||
jobject CreateSurface();
|
||||
void DestroySurface(jobject surface);
|
||||
void ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend);
|
||||
void HideSurface(jobject surface);
|
||||
|
||||
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen);
|
||||
void RemovePluginView(jobject view, bool isFullScreen);
|
||||
|
||||
@ -356,13 +357,6 @@ public:
|
||||
|
||||
void NotifyWakeLockChanged(const nsAString& topic, const nsAString& state);
|
||||
|
||||
int GetAPIVersion() { return mAPIVersion; }
|
||||
bool IsHoneycomb() { return mAPIVersion >= 11 && mAPIVersion <= 13; }
|
||||
|
||||
void ScheduleComposite();
|
||||
void RegisterSurfaceTextureFrameListener(jobject surfaceTexture, int id);
|
||||
void UnregisterSurfaceTextureFrameListener(jobject surfaceTexture);
|
||||
|
||||
void GetGfxInfoData(nsACString& aRet);
|
||||
|
||||
protected:
|
||||
@ -396,8 +390,6 @@ protected:
|
||||
bool mHasNativeWindowAccess;
|
||||
bool mHasNativeWindowFallback;
|
||||
|
||||
int mAPIVersion;
|
||||
|
||||
nsCOMArray<nsIRunnable> mRunnableQueue;
|
||||
|
||||
// other things
|
||||
@ -487,8 +479,6 @@ protected:
|
||||
jmethodID jUnlockScreenOrientation;
|
||||
jmethodID jPumpMessageLoop;
|
||||
jmethodID jNotifyWakeLockChanged;
|
||||
jmethodID jRegisterSurfaceTextureFrameListener;
|
||||
jmethodID jUnregisterSurfaceTextureFrameListener;
|
||||
|
||||
// for GfxInfo (gfx feature detection and blacklisting)
|
||||
jmethodID jGetGfxInfoData;
|
||||
@ -517,7 +507,6 @@ protected:
|
||||
int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
|
||||
|
||||
void* (*ANativeWindow_fromSurface)(JNIEnv *env, jobject surface);
|
||||
void* (*ANativeWindow_fromSurfaceTexture)(JNIEnv *env, jobject surfaceTexture);
|
||||
void (*ANativeWindow_release)(void *window);
|
||||
int (*ANativeWindow_setBuffersGeometry)(void *window, int width, int height, int format);
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "nsISmsRequestManager.h"
|
||||
#include "nsISmsDatabaseService.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
#include "nsSurfaceTexture.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom::sms;
|
||||
@ -1024,17 +1023,5 @@ Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue(JNIEnv* jenv, jclas
|
||||
return msg;
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_onSurfaceTextureFrameAvailable(JNIEnv* jenv, jclass, jobject surfaceTexture, jint id)
|
||||
{
|
||||
nsSurfaceTexture* st = nsSurfaceTexture::Find(id);
|
||||
if (!st) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoJNI", "Failed to find nsSurfaceTexture with id %d", id);
|
||||
return;
|
||||
}
|
||||
|
||||
st->NotifyFrameAvailable();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
148
widget/android/AndroidMediaLayer.cpp
Normal file
148
widget/android/AndroidMediaLayer.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <android/log.h>
|
||||
#include "AndroidMediaLayer.h"
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidMediaLayer" , ## args)
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
AndroidMediaLayer::AndroidMediaLayer()
|
||||
: mInverted(false), mVisible(true) {
|
||||
}
|
||||
|
||||
AndroidMediaLayer::~AndroidMediaLayer() {
|
||||
if (mContentData.window && AndroidBridge::Bridge()) {
|
||||
AndroidBridge::Bridge()->ReleaseNativeWindow(mContentData.window);
|
||||
mContentData.window = NULL;
|
||||
}
|
||||
|
||||
if (mContentData.surface && AndroidBridge::Bridge()) {
|
||||
AndroidBridge::Bridge()->DestroySurface(mContentData.surface);
|
||||
mContentData.surface = NULL;
|
||||
}
|
||||
|
||||
std::map<void*, SurfaceData*>::iterator it;
|
||||
|
||||
for (it = mVideoSurfaces.begin(); it != mVideoSurfaces.end(); it++) {
|
||||
SurfaceData* data = it->second;
|
||||
|
||||
if (AndroidBridge::Bridge()) {
|
||||
AndroidBridge::Bridge()->ReleaseNativeWindow(data->window);
|
||||
AndroidBridge::Bridge()->DestroySurface(data->surface);
|
||||
}
|
||||
|
||||
delete data;
|
||||
}
|
||||
|
||||
mVideoSurfaces.clear();
|
||||
}
|
||||
|
||||
bool AndroidMediaLayer::EnsureContentSurface() {
|
||||
if (!mContentData.surface && AndroidBridge::Bridge()) {
|
||||
mContentData.surface = AndroidBridge::Bridge()->CreateSurface();
|
||||
if (mContentData.surface) {
|
||||
mContentData.window = AndroidBridge::Bridge()->AcquireNativeWindow(AndroidBridge::GetJNIEnv(), mContentData.surface);
|
||||
AndroidBridge::Bridge()->SetNativeWindowFormat(mContentData.window, 0, 0, AndroidBridge::WINDOW_FORMAT_RGBA_8888);
|
||||
}
|
||||
}
|
||||
|
||||
return mContentData.surface && mContentData.window;
|
||||
}
|
||||
|
||||
void* AndroidMediaLayer::GetNativeWindowForContent() {
|
||||
if (!EnsureContentSurface())
|
||||
return NULL;
|
||||
|
||||
return mContentData.window;
|
||||
}
|
||||
|
||||
void* AndroidMediaLayer::RequestNativeWindowForVideo() {
|
||||
if (!AndroidBridge::Bridge())
|
||||
return NULL;
|
||||
|
||||
jobject surface = AndroidBridge::Bridge()->CreateSurface();
|
||||
if (surface) {
|
||||
void* window = AndroidBridge::Bridge()->AcquireNativeWindow(AndroidBridge::GetJNIEnv(), surface);
|
||||
if (window) {
|
||||
AndroidBridge::Bridge()->SetNativeWindowFormat(window, 0, 0, AndroidBridge::WINDOW_FORMAT_RGBA_8888);
|
||||
mVideoSurfaces[window] = new SurfaceData(surface, window);
|
||||
return window;
|
||||
} else {
|
||||
LOG("Failed to create native window from surface");
|
||||
|
||||
// Cleanup
|
||||
AndroidBridge::Bridge()->DestroySurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AndroidMediaLayer::ReleaseNativeWindowForVideo(void* aWindow) {
|
||||
if (mVideoSurfaces.find(aWindow) == mVideoSurfaces.end() || !AndroidBridge::Bridge())
|
||||
return;
|
||||
|
||||
SurfaceData* data = mVideoSurfaces[aWindow];
|
||||
|
||||
AndroidBridge::Bridge()->ReleaseNativeWindow(data->window);
|
||||
AndroidBridge::Bridge()->DestroySurface(data->surface);
|
||||
|
||||
mVideoSurfaces.erase(aWindow);
|
||||
delete data;
|
||||
}
|
||||
|
||||
void AndroidMediaLayer::SetNativeWindowDimensions(void* aWindow, const gfxRect& aDimensions) {
|
||||
if (mVideoSurfaces.find(aWindow) == mVideoSurfaces.end())
|
||||
return;
|
||||
|
||||
SurfaceData* data = mVideoSurfaces[aWindow];
|
||||
data->dimensions = aDimensions;
|
||||
}
|
||||
|
||||
void AndroidMediaLayer::UpdatePosition(const gfxRect& aRect) {
|
||||
if (!mVisible || !AndroidBridge::Bridge())
|
||||
return;
|
||||
|
||||
std::map<void*, SurfaceData*>::iterator it;
|
||||
|
||||
for (it = mVideoSurfaces.begin(); it != mVideoSurfaces.end(); it++) {
|
||||
SurfaceData* data = it->second;
|
||||
|
||||
gfxRect videoRect(aRect.x + data->dimensions.x, aRect.y + data->dimensions.y,
|
||||
data->dimensions.width, data->dimensions.height);
|
||||
|
||||
AndroidBridge::Bridge()->ShowSurface(data->surface, videoRect, mInverted, false);
|
||||
}
|
||||
|
||||
if (EnsureContentSurface()) {
|
||||
AndroidBridge::Bridge()->ShowSurface(mContentData.surface, aRect, mInverted, true);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidMediaLayer::SetVisible(bool aVisible) {
|
||||
if (aVisible == mVisible || !AndroidBridge::Bridge())
|
||||
return;
|
||||
|
||||
mVisible = aVisible;
|
||||
if (mVisible)
|
||||
return;
|
||||
|
||||
// Hide all surfaces
|
||||
std::map<void*, SurfaceData*>::iterator it;
|
||||
|
||||
if (EnsureContentSurface())
|
||||
AndroidBridge::Bridge()->HideSurface(mContentData.surface);
|
||||
|
||||
for (it = mVideoSurfaces.begin(); it != mVideoSurfaces.end(); it++) {
|
||||
SurfaceData* data = it->second;
|
||||
AndroidBridge::Bridge()->HideSurface(data->surface);
|
||||
}
|
||||
}
|
||||
|
||||
} /* mozilla */
|
73
widget/android/AndroidMediaLayer.h
Normal file
73
widget/android/AndroidMediaLayer.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef AndroidMediaLayer_h_
|
||||
#define AndroidMediaLayer_h_
|
||||
|
||||
#include <map>
|
||||
#include <jni.h>
|
||||
#include "gfxRect.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class AndroidMediaLayer
|
||||
{
|
||||
public:
|
||||
AndroidMediaLayer();
|
||||
virtual ~AndroidMediaLayer();
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(AndroidMediaLayer)
|
||||
|
||||
void* GetNativeWindowForContent();
|
||||
|
||||
void* RequestNativeWindowForVideo();
|
||||
void ReleaseNativeWindowForVideo(void* aWindow);
|
||||
|
||||
void SetNativeWindowDimensions(void* aWindow, const gfxRect& aDimensions);
|
||||
|
||||
void UpdatePosition(const gfxRect& aRect);
|
||||
|
||||
bool Inverted() {
|
||||
return mInverted;
|
||||
}
|
||||
|
||||
void SetInverted(bool aInverted) {
|
||||
mInverted = aInverted;
|
||||
}
|
||||
|
||||
bool IsVisible() {
|
||||
return mVisible;
|
||||
}
|
||||
|
||||
void SetVisible(bool aVisible);
|
||||
|
||||
private:
|
||||
bool mInverted;
|
||||
bool mVisible;
|
||||
|
||||
class SurfaceData {
|
||||
public:
|
||||
SurfaceData() :
|
||||
surface(NULL), window(NULL) {
|
||||
}
|
||||
|
||||
SurfaceData(jobject aSurface, void* aWindow) :
|
||||
surface(aSurface), window(aWindow) {
|
||||
}
|
||||
|
||||
jobject surface;
|
||||
void* window;
|
||||
gfxRect dimensions;
|
||||
};
|
||||
|
||||
bool EnsureContentSurface();
|
||||
|
||||
SurfaceData mContentData;
|
||||
std::map<void*, SurfaceData*> mVideoSurfaces;
|
||||
};
|
||||
|
||||
} /* mozilla */
|
||||
#endif /* AndroidMediaLayer_h_ */
|
@ -32,6 +32,7 @@ CPPSRCS = \
|
||||
AndroidLayerViewWrapper.cpp \
|
||||
AndroidGraphicBuffer.cpp \
|
||||
AndroidJNI.cpp \
|
||||
AndroidMediaLayer.cpp \
|
||||
nsWindow.cpp \
|
||||
nsLookAndFeel.cpp \
|
||||
nsScreenManagerAndroid.cpp \
|
||||
@ -73,7 +74,6 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/docshell/base \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
-I$(topsrcdir)/netwerk/cache \
|
||||
-I$(topsrcdir)/widget/android/android \
|
||||
-I$(srcdir) \
|
||||
$(NULL)
|
||||
|
||||
|
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* WARNING: EVERYTHING HERE IS NEUTERED
|
||||
*
|
||||
* The only reason we need this is to be able to call
|
||||
* android_SurfaceTexture_getNativeWindow, which returns a
|
||||
* android::sp<ANativeWindow>. Therefore, we need the definition of
|
||||
* android::sp (below) in order to get the pointer out. All of the actual
|
||||
* ref management stuff is commented out by Mozilla. Do not try to use this
|
||||
* for anything real.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_STRONG_POINTER_H
|
||||
#define ANDROID_STRONG_POINTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
|
||||
class TextOutput;
|
||||
TextOutput& printStrongPointer(TextOutput& to, const void* val);
|
||||
|
||||
template<typename T> class wp;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define COMPARE(_op_) \
|
||||
inline bool operator _op_ (const sp<T>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
inline bool operator _op_ (const T* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const sp<U>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const U* o) const { \
|
||||
return m_ptr _op_ o; \
|
||||
} \
|
||||
inline bool operator _op_ (const wp<T>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
} \
|
||||
template<typename U> \
|
||||
inline bool operator _op_ (const wp<U>& o) const { \
|
||||
return m_ptr _op_ o.m_ptr; \
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
class sp
|
||||
{
|
||||
public:
|
||||
inline sp() : m_ptr(0) { }
|
||||
|
||||
sp(T* other);
|
||||
sp(const sp<T>& other);
|
||||
template<typename U> sp(U* other);
|
||||
template<typename U> sp(const sp<U>& other);
|
||||
|
||||
~sp();
|
||||
|
||||
// Assignment
|
||||
|
||||
sp& operator = (T* other);
|
||||
sp& operator = (const sp<T>& other);
|
||||
|
||||
template<typename U> sp& operator = (const sp<U>& other);
|
||||
template<typename U> sp& operator = (U* other);
|
||||
|
||||
//! Special optimization for use by ProcessState (and nobody else).
|
||||
void force_set(T* other);
|
||||
|
||||
// Reset
|
||||
|
||||
void clear();
|
||||
|
||||
// Accessors
|
||||
|
||||
inline T& operator* () const { return *m_ptr; }
|
||||
inline T* operator-> () const { return m_ptr; }
|
||||
inline T* get() const { return m_ptr; }
|
||||
|
||||
// Operators
|
||||
|
||||
COMPARE(==)
|
||||
COMPARE(!=)
|
||||
COMPARE(>)
|
||||
COMPARE(<)
|
||||
COMPARE(<=)
|
||||
COMPARE(>=)
|
||||
|
||||
private:
|
||||
template<typename Y> friend class sp;
|
||||
template<typename Y> friend class wp;
|
||||
void set_pointer(T* ptr);
|
||||
T* m_ptr;
|
||||
};
|
||||
|
||||
#undef COMPARE
|
||||
|
||||
template <typename T>
|
||||
TextOutput& operator<<(TextOutput& to, const sp<T>& val);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No user serviceable parts below here.
|
||||
|
||||
template<typename T>
|
||||
sp<T>::sp(T* other)
|
||||
: m_ptr(other)
|
||||
{
|
||||
//if (other) other->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>::sp(const sp<T>& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
//if (m_ptr) m_ptr->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>::sp(U* other) : m_ptr(other)
|
||||
{
|
||||
//if (other) ((T*)other)->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>::sp(const sp<U>& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{
|
||||
//if (m_ptr) m_ptr->incStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>::~sp()
|
||||
{
|
||||
//if (m_ptr) m_ptr->decStrong(this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>& sp<T>::operator = (const sp<T>& other) {
|
||||
T* otherPtr(other.m_ptr);
|
||||
/*
|
||||
if (otherPtr) otherPtr->incStrong(this);
|
||||
if (m_ptr) m_ptr->decStrong(this);
|
||||
*/
|
||||
m_ptr = otherPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
sp<T>& sp<T>::operator = (T* other)
|
||||
{
|
||||
/*
|
||||
if (other) other->incStrong(this);
|
||||
if (m_ptr) m_ptr->decStrong(this);
|
||||
*/
|
||||
m_ptr = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>& sp<T>::operator = (const sp<U>& other)
|
||||
{
|
||||
T* otherPtr(other.m_ptr);
|
||||
/*
|
||||
if (otherPtr) otherPtr->incStrong(this);
|
||||
if (m_ptr) m_ptr->decStrong(this);
|
||||
*/
|
||||
m_ptr = otherPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> template<typename U>
|
||||
sp<T>& sp<T>::operator = (U* other)
|
||||
{
|
||||
/*
|
||||
if (other) ((T*)other)->incStrong(this);
|
||||
if (m_ptr) m_ptr->decStrong(this);
|
||||
*/
|
||||
m_ptr = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::force_set(T* other)
|
||||
{
|
||||
//other->forceIncStrong(this);
|
||||
m_ptr = other;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::clear()
|
||||
{
|
||||
if (m_ptr) {
|
||||
m_ptr->decStrong(this);
|
||||
m_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void sp<T>::set_pointer(T* ptr) {
|
||||
m_ptr = ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
|
||||
{
|
||||
return printStrongPointer(to, val.get());
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_STRONG_POINTER_H
|
Loading…
Reference in New Issue
Block a user