Merge the last PGO-green inbound changeset to m-c.

This commit is contained in:
Ryan VanderMeulen 2012-07-22 12:19:17 -04:00
commit b63e497f2a
99 changed files with 1359 additions and 2198 deletions

View File

@ -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;
}

View File

@ -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 \

View File

@ -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>

View File

@ -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);

View File

@ -68,7 +68,7 @@ nsSVGSwitchElement::MaybeInvalidate()
nsIFrame *frame = GetPrimaryFrame();
if (frame) {
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(frame);
nsSVGUtils::InvalidateAndScheduleReflowSVG(frame);
}
mActiveChild = newActiveChild;

View File

@ -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.");

View File

@ -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.

View File

@ -59,7 +59,6 @@ BrowserElementChild.prototype = {
BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
docShell.setIsBrowser();
docShell.QueryInterface(Ci.nsIWebProgress)
.addProgressListener(this._progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION |

View File

@ -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;
}

View File

@ -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&);

View File

@ -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){

View File

@ -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&);

View File

@ -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();

View File

@ -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"));
}

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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) {

View File

@ -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)

View File

@ -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
};

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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
*/

View File

@ -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;
}

View File

@ -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

View File

@ -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();

View File

@ -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.
*/

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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();

View File

@ -40,7 +40,6 @@ struct SharedTextureDescriptor {
TextureShareType shareType;
SharedTextureHandle handle;
nsIntSize size;
bool inverted;
};
struct SurfaceDescriptorGralloc {

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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\

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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)) {

View File

@ -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");

View 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

View 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

View File

@ -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

View File

@ -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);
}

View File

@ -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 &&

View File

@ -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;

View File

@ -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

View File

@ -107,7 +107,7 @@ nsSVGAFrame::AttributeChanged(PRInt32 aNameSpaceID,
{
if (aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::transform) {
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
NotifySVGChanged(TRANSFORM_CHANGED);
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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);

View File

@ -95,7 +95,7 @@ nsSVGGFrame::AttributeChanged(PRInt32 aNameSpaceID,
{
if (aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::transform) {
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
NotifySVGChanged(TRANSFORM_CHANGED);
}

View File

@ -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();

View File

@ -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; }

View File

@ -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;
}

View File

@ -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 ?

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -80,7 +80,7 @@ nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy ||
aAttribute == nsGkAtoms::rotate)) {
nsSVGUtils::InvalidateAndScheduleBoundsUpdate(this);
nsSVGUtils::InvalidateAndScheduleReflowSVG(this);
NotifyGlyphMetricsChange();
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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!");

View File

@ -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

View File

@ -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();
}

View File

@ -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 {

View File

@ -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 \

View 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;
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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
}

View 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 */

View 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_ */

View File

@ -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)

View File

@ -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