mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to m-c.
This commit is contained in:
commit
ca60a72df2
@ -452,13 +452,13 @@ pref("app.update.staging.enabled", true);
|
||||
pref("app.update.service.enabled", true);
|
||||
|
||||
// The URL hosting the update manifest.
|
||||
pref("app.update.url", "http://update.boot2gecko.org/m2.5/updates.xml");
|
||||
pref("app.update.url", "http://update.boot2gecko.org/nightly/update.xml");
|
||||
// Interval at which update manifest is fetched. In units of seconds.
|
||||
pref("app.update.interval", 3600); // 1 hour
|
||||
pref("app.update.interval", 86400); // 1 day
|
||||
// First interval to elapse before checking for update. In units of
|
||||
// milliseconds. Capped at 10 seconds.
|
||||
pref("app.update.timerFirstInterval", 30000);
|
||||
pref("app.update.timerMinimumDelay", 30); // seconds
|
||||
pref("app.update.timerFirstInterval", 3600000); // 1 hour
|
||||
pref("app.update.timerMinimumDelay", 3600); // 1 hour in seconds
|
||||
// Don't throttle background updates.
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
|
||||
|
@ -2394,6 +2394,9 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
mMayStartLayout = false;
|
||||
|
||||
mHaveInputEncoding = true;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
nsresult rv = InitCSP(aChannel, getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aReset) {
|
||||
Reset(aChannel, aLoadGroup);
|
||||
@ -2423,29 +2426,39 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsresult rv = InitCSP();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (csp) {
|
||||
// Copy into principal
|
||||
nsIPrincipal* principal = GetPrincipal();
|
||||
principal->SetCsp(csp);
|
||||
#ifdef PR_LOGGING
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("Inserted CSP into principal %p", principal));
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::InitCSP()
|
||||
nsDocument::InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP)
|
||||
{
|
||||
*aCSP = nullptr;
|
||||
if (CSPService::sCSPEnabled) {
|
||||
nsAutoString cspHeaderValue;
|
||||
nsAutoString cspROHeaderValue;
|
||||
|
||||
this->GetHeaderData(nsGkAtoms::headerCSP, cspHeaderValue);
|
||||
this->GetHeaderData(nsGkAtoms::headerCSPReportOnly, cspROHeaderValue);
|
||||
|
||||
bool system = false;
|
||||
nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
|
||||
|
||||
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(NodePrincipal(), &system)) && system) {
|
||||
// only makes sense to register new CSP if this document is not priviliged
|
||||
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (!httpChannel) {
|
||||
// no CSP for non http channels
|
||||
return NS_OK;
|
||||
}
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy"),
|
||||
tCspHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("x-content-security-policy-report-only"),
|
||||
tCspROHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
|
||||
|
||||
if (cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) {
|
||||
// no CSP header present, stop processing
|
||||
@ -2457,8 +2470,8 @@ nsDocument::InitCSP()
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
mCSP = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef PR_LOGGING
|
||||
@ -2468,12 +2481,11 @@ nsDocument::InitCSP()
|
||||
}
|
||||
|
||||
// Store the request context for violation reports
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
||||
mCSP->ScanRequestData(httpChannel);
|
||||
csp->ScanRequestData(httpChannel);
|
||||
|
||||
// Start parsing the policy
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
mChannel->GetURI(getter_AddRefs(chanURI));
|
||||
aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP Loaded"));
|
||||
@ -2484,7 +2496,7 @@ nsDocument::InitCSP()
|
||||
// toss a warning into the error console, proceeding with enforcing the
|
||||
// regular-strength CSP.
|
||||
if (cspHeaderValue.IsEmpty()) {
|
||||
mCSP->SetReportOnlyMode(true);
|
||||
csp->SetReportOnlyMode(true);
|
||||
|
||||
// Need to tokenize the header value since multiple headers could be
|
||||
// concatenated into one comma-separated list of policies.
|
||||
@ -2492,7 +2504,7 @@ nsDocument::InitCSP()
|
||||
nsCharSeparatedTokenizer tokenizer(cspROHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
mCSP->RefinePolicy(policy, chanURI);
|
||||
csp->RefinePolicy(policy, chanURI);
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
@ -2511,7 +2523,7 @@ nsDocument::InitCSP()
|
||||
nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
mCSP->RefinePolicy(policy, chanURI);
|
||||
csp->RefinePolicy(policy, chanURI);
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
@ -2528,7 +2540,7 @@ nsDocument::InitCSP()
|
||||
bool safeAncestry = false;
|
||||
|
||||
// PermitsAncestry sends violation reports when necessary
|
||||
rv = mCSP->PermitsAncestry(docShell, &safeAncestry);
|
||||
rv = csp->PermitsAncestry(docShell, &safeAncestry);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!safeAncestry) {
|
||||
@ -2537,24 +2549,10 @@ nsDocument::InitCSP()
|
||||
("CSP doesn't like frame's ancestry, not loading."));
|
||||
#endif
|
||||
// stop! ERROR page!
|
||||
mChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
|
||||
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
|
||||
}
|
||||
}
|
||||
|
||||
//Copy into principal
|
||||
nsIPrincipal* principal = GetPrincipal();
|
||||
|
||||
if (principal) {
|
||||
principal->SetCsp(mCSP);
|
||||
#ifdef PR_LOGGING
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("Inserted CSP into principal %p", principal));
|
||||
}
|
||||
else {
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("Couldn't copy CSP into absent principal %p", principal));
|
||||
#endif
|
||||
}
|
||||
csp.forget(aCSP);
|
||||
}
|
||||
#ifdef PR_LOGGING
|
||||
else { //CSP was not enabled!
|
||||
@ -6791,8 +6789,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||
"content-disposition",
|
||||
"refresh",
|
||||
"x-dns-prefetch-control",
|
||||
"x-content-security-policy",
|
||||
"x-content-security-policy-report-only",
|
||||
"x-frame-options",
|
||||
// add more http headers if you need
|
||||
// XXXbz don't add content-location support without reading bug
|
||||
|
@ -1274,7 +1274,7 @@ private:
|
||||
void DoUnblockOnload();
|
||||
|
||||
nsresult CheckFrameOptions();
|
||||
nsresult InitCSP();
|
||||
nsresult InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP);
|
||||
|
||||
// Sets aElement to be the pending pointer lock element. Once this document's
|
||||
// node principal's URI is granted the "fullscreen" permission, the pointer
|
||||
|
@ -440,7 +440,10 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
LOG("agent handler %s: Unhandled event. Ignore.", __FUNCTION__);
|
||||
#endif
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
if (!errorStr.IsEmpty()) {
|
||||
@ -669,8 +672,18 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
|
||||
dbus_message_iter_recurse(&aIter, &prop_val);
|
||||
type = aPropertyTypes[*aPropIndex].type;
|
||||
|
||||
NS_ASSERTION(dbus_message_iter_get_arg_type(&prop_val) == type,
|
||||
"Iterator not type we expect!");
|
||||
if(dbus_message_iter_get_arg_type(&prop_val) != type) {
|
||||
NS_WARNING("Iterator not type we expect!");
|
||||
nsAutoCString str;
|
||||
str += "Property Name: ;";
|
||||
str += NS_ConvertUTF16toUTF8(propertyName);
|
||||
str += " Property Type Expected: ;";
|
||||
str += type;
|
||||
str += " Property Type Received: ";
|
||||
str += dbus_message_iter_get_arg_type(&prop_val);
|
||||
NS_WARNING(str.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
BluetoothValue propertyValue;
|
||||
switch (type) {
|
||||
@ -982,6 +995,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
signalStr += " Signal not handled!";
|
||||
NS_WARNING(signalStr.get());
|
||||
#endif
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
if (!errorStr.IsEmpty()) {
|
||||
@ -1077,8 +1091,6 @@ BluetoothDBusService::StopInternal()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RemoveReservedServicesInternal(sDefaultAdapterPath, sServiceHandles);
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
for (uint32_t i = 0; i < ArrayLength(sBluetoothDBusSignals); ++i) {
|
||||
@ -1167,7 +1179,6 @@ public:
|
||||
path));
|
||||
|
||||
RegisterAgent(path);
|
||||
AddReservedServices(path);
|
||||
|
||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||
|
||||
|
@ -292,6 +292,13 @@ child:
|
||||
*/
|
||||
HandleDoubleTap(nsIntPoint point);
|
||||
|
||||
/**
|
||||
* Requests handling of a single tap. |point| is in CSS pixels, relative to
|
||||
* the scroll offset. This message is expected to send a "mousedown" and
|
||||
* "mouseup" series of events at this point.
|
||||
*/
|
||||
HandleSingleTap(nsIntPoint point);
|
||||
|
||||
/**
|
||||
* Sending an activate message moves focus to the child.
|
||||
*/
|
||||
|
@ -888,6 +888,19 @@ TabChild::RecvHandleDoubleTap(const nsIntPoint& aPoint)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvHandleSingleTap(const nsIntPoint& aPoint)
|
||||
{
|
||||
if (!mCx || !mTabChildGlobal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RecvMouseEvent(NS_LITERAL_STRING("mousedown"), aPoint.x, aPoint.y, 0, 1, 0, false);
|
||||
RecvMouseEvent(NS_LITERAL_STRING("mouseup"), aPoint.x, aPoint.y, 0, 1, 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvActivate()
|
||||
{
|
||||
@ -936,61 +949,67 @@ TabChild::RecvMouseWheelEvent(const WheelEvent& event)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent)
|
||||
{
|
||||
// Synthesize a phony mouse event.
|
||||
uint32_t msg;
|
||||
switch (aEvent.message) {
|
||||
case NS_TOUCH_START:
|
||||
msg = NS_MOUSE_BUTTON_DOWN;
|
||||
break;
|
||||
case NS_TOUCH_MOVE:
|
||||
msg = NS_MOUSE_MOVE;
|
||||
break;
|
||||
case NS_TOUCH_END:
|
||||
case NS_TOUCH_CANCEL:
|
||||
msg = NS_MOUSE_BUTTON_UP;
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown touch event message");
|
||||
}
|
||||
|
||||
nsIntPoint refPoint(0, 0);
|
||||
if (aEvent.touches.Length()) {
|
||||
refPoint = aEvent.touches[0]->mRefPoint;
|
||||
}
|
||||
|
||||
nsMouseEvent event(true, msg, NULL,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
event.refPoint = refPoint;
|
||||
event.time = aEvent.time;
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
if (msg != NS_MOUSE_MOVE) {
|
||||
event.clickCount = 1;
|
||||
}
|
||||
|
||||
DispatchWidgetEvent(event);
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealTouchEvent(const nsTouchEvent& aEvent)
|
||||
{
|
||||
nsTouchEvent localEvent(aEvent);
|
||||
nsEventStatus status = DispatchWidgetEvent(localEvent);
|
||||
nsTouchEvent localEvent(aEvent);
|
||||
nsEventStatus status = DispatchWidgetEvent(localEvent);
|
||||
|
||||
if (IsAsyncPanZoomEnabled()) {
|
||||
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(mWebNav);
|
||||
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
|
||||
|
||||
if (innerWindow && innerWindow->HasTouchEventListeners()) {
|
||||
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
|
||||
}
|
||||
} else if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
DispatchSynthesizedMouseEvent(aEvent);
|
||||
}
|
||||
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Synthesize a phony mouse event.
|
||||
uint32_t msg;
|
||||
switch (aEvent.message) {
|
||||
case NS_TOUCH_START:
|
||||
msg = NS_MOUSE_BUTTON_DOWN;
|
||||
break;
|
||||
case NS_TOUCH_MOVE:
|
||||
msg = NS_MOUSE_MOVE;
|
||||
break;
|
||||
case NS_TOUCH_END:
|
||||
case NS_TOUCH_CANCEL:
|
||||
msg = NS_MOUSE_BUTTON_UP;
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown touch event message");
|
||||
}
|
||||
|
||||
nsIntPoint refPoint(0, 0);
|
||||
if (aEvent.touches.Length()) {
|
||||
refPoint = aEvent.touches[0]->mRefPoint;
|
||||
}
|
||||
|
||||
nsMouseEvent event(true, msg, NULL,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
event.refPoint = refPoint;
|
||||
event.time = aEvent.time;
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
if (msg != NS_MOUSE_MOVE) {
|
||||
event.clickCount = 1;
|
||||
}
|
||||
|
||||
DispatchWidgetEvent(event);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealTouchMoveEvent(const nsTouchEvent& aEvent)
|
||||
{
|
||||
return RecvRealTouchEvent(aEvent);
|
||||
return RecvRealTouchEvent(aEvent);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -183,6 +183,7 @@ public:
|
||||
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
|
||||
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
|
||||
virtual bool RecvHandleSingleTap(const nsIntPoint& aPoint);
|
||||
virtual bool RecvActivate();
|
||||
virtual bool RecvDeactivate();
|
||||
virtual bool RecvMouseEvent(const nsString& aType,
|
||||
@ -323,6 +324,9 @@ private:
|
||||
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
const nsACString& aJSONData);
|
||||
|
||||
// Sends a simulated mouse event from a touch event for compatibility.
|
||||
void DispatchSynthesizedMouseEvent(const nsTouchEvent& aEvent);
|
||||
|
||||
nsresult
|
||||
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
nsIURI* aURI,
|
||||
|
@ -252,6 +252,11 @@ void TabParent::HandleDoubleTap(const nsIntPoint& aPoint)
|
||||
unused << SendHandleDoubleTap(aPoint);
|
||||
}
|
||||
|
||||
void TabParent::HandleSingleTap(const nsIntPoint& aPoint)
|
||||
{
|
||||
unused << SendHandleSingleTap(aPoint);
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::Activate()
|
||||
{
|
||||
|
@ -152,6 +152,7 @@ public:
|
||||
void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
|
||||
void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
|
||||
void HandleDoubleTap(const nsIntPoint& aPoint);
|
||||
void HandleSingleTap(const nsIntPoint& aPoint);
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
|
||||
|
@ -28,6 +28,10 @@ In this order:
|
||||
see bug 680840. Probably not useful anymore now that we're on the new
|
||||
preprocessor, but it doesn't hurt to keep it around a bit longer.
|
||||
|
||||
angle-faceforward-emu.patch
|
||||
See bug 771406. Adds emulation for faceforward(float,float,float),
|
||||
which is needed to prevent crashing on Mac+Intel.
|
||||
|
||||
In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
|
||||
Therefore, changes made to the Makefile.in files should not be stored in the local .patch files.
|
||||
|
||||
|
314
gfx/angle/angle-faceforward-emu.patch
Normal file
314
gfx/angle/angle-faceforward-emu.patch
Normal file
@ -0,0 +1,314 @@
|
||||
From: Jeff Gilbert <jgilbert@mozilla.com>
|
||||
Bug 771406 - Add emulation for GLSL faceforward() to ANGLE - r=bjacob
|
||||
|
||||
diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
|
||||
--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
|
||||
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.cpp
|
||||
@@ -26,16 +26,22 @@ const char* kFunctionEmulationVertexSour
|
||||
"#error no emulation for distance(vec3, vec3)",
|
||||
"#error no emulation for distance(vec4, vec4)",
|
||||
|
||||
"#define webgl_dot_emu(x, y) ((x) * (y))",
|
||||
"#error no emulation for dot(vec2, vec2)",
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
+ // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
+ "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
+ "#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
+ "#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
+ "#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
+
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
"#error no emulation for length(vec4)",
|
||||
|
||||
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
|
||||
"#error no emulation for normalize(vec2)",
|
||||
"#error no emulation for normalize(vec3)",
|
||||
@@ -58,16 +64,22 @@ const char* kFunctionEmulationFragmentSo
|
||||
"#error no emulation for distance(vec3, vec3)",
|
||||
"#error no emulation for distance(vec4, vec4)",
|
||||
|
||||
"#define webgl_dot_emu(x, y) ((x) * (y))",
|
||||
"#error no emulation for dot(vec2, vec2)",
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
+ // |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
+ "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
+ "#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
+ "#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
+ "#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
+
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
"#error no emulation for length(vec4)",
|
||||
|
||||
"#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
|
||||
"#error no emulation for normalize(vec2)",
|
||||
"#error no emulation for normalize(vec3)",
|
||||
@@ -89,16 +101,20 @@ const bool kFunctionEmulationVertexMask[
|
||||
true, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
true, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
+ true, // TFunctionFaceForward1_1_1
|
||||
+ false, // TFunctionFaceForward2_2_2
|
||||
+ false, // TFunctionFaceForward3_3_3
|
||||
+ false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
true, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
@@ -115,16 +131,20 @@ const bool kFunctionEmulationVertexMask[
|
||||
false, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
false, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
+ false, // TFunctionFaceForward1_1_1
|
||||
+ false, // TFunctionFaceForward2_2_2
|
||||
+ false, // TFunctionFaceForward3_3_3
|
||||
+ false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
false, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
@@ -146,16 +166,20 @@ const bool kFunctionEmulationFragmentMas
|
||||
true, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
true, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
+ true, // TFunctionFaceForward1_1_1
|
||||
+ false, // TFunctionFaceForward2_2_2
|
||||
+ false, // TFunctionFaceForward3_3_3
|
||||
+ false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
true, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
@@ -172,16 +196,20 @@ const bool kFunctionEmulationFragmentMas
|
||||
false, // TFunctionDistance1_1
|
||||
false, // TFunctionDistance2_2
|
||||
false, // TFunctionDistance3_3
|
||||
false, // TFunctionDistance4_4
|
||||
false, // TFunctionDot1_1
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
+ false, // TFunctionFaceForward1_1_1
|
||||
+ false, // TFunctionFaceForward2_2_2
|
||||
+ false, // TFunctionFaceForward3_3_3
|
||||
+ false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
false, // TFunctionLength4
|
||||
false, // TFunctionNormalize1
|
||||
false, // TFunctionNormalize2
|
||||
false, // TFunctionNormalize3
|
||||
false, // TFunctionNormalize4
|
||||
@@ -239,25 +267,37 @@ public:
|
||||
case EOpReflect:
|
||||
case EOpRefract:
|
||||
case EOpMul:
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
};
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
- // Right now we only handle built-in functions with two parameters.
|
||||
- if (sequence.size() != 2)
|
||||
+ bool needToEmulate = false;
|
||||
+
|
||||
+ if (sequence.size() == 2) {
|
||||
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
+ if (!param1 || !param2)
|
||||
+ return true;
|
||||
+ needToEmulate = mEmulator.SetFunctionCalled(
|
||||
+ node->getOp(), param1->getType(), param2->getType());
|
||||
+ } else if (sequence.size() == 3) {
|
||||
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
+ TIntermTyped* param3 = sequence[2]->getAsTyped();
|
||||
+ if (!param1 || !param2 || !param3)
|
||||
+ return true;
|
||||
+ needToEmulate = mEmulator.SetFunctionCalled(
|
||||
+ node->getOp(), param1->getType(), param2->getType(), param3->getType());
|
||||
+ } else {
|
||||
return true;
|
||||
- TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
- TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
- if (!param1 || !param2)
|
||||
- return true;
|
||||
- bool needToEmulate = mEmulator.SetFunctionCalled(
|
||||
- node->getOp(), param1->getType(), param2->getType());
|
||||
+ }
|
||||
+
|
||||
if (needToEmulate)
|
||||
node->setUseEmulatedFunction();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
BuiltInFunctionEmulator& mEmulator;
|
||||
@@ -286,16 +326,23 @@ bool BuiltInFunctionEmulator::SetFunctio
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param1, param2);
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
+ TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
+{
|
||||
+ TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
|
||||
+ return SetFunctionCalled(function);
|
||||
+}
|
||||
+
|
||||
+bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
BuiltInFunctionEmulator::TBuiltInFunction function) {
|
||||
if (function == TFunctionUnknown || mFunctionMask[function] == false)
|
||||
return false;
|
||||
for (size_t i = 0; i < mFunctions.size(); ++i) {
|
||||
if (mFunctions[i] == function)
|
||||
return true;
|
||||
}
|
||||
mFunctions.push_back(function);
|
||||
@@ -377,16 +424,44 @@ BuiltInFunctionEmulator::IdentifyFunctio
|
||||
}
|
||||
if (function == TFunctionUnknown)
|
||||
return TFunctionUnknown;
|
||||
if (param1.isVector())
|
||||
function += param1.getNominalSize() - 1;
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
+BuiltInFunctionEmulator::TBuiltInFunction
|
||||
+BuiltInFunctionEmulator::IdentifyFunction(
|
||||
+ TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
+{
|
||||
+ // Check that all params have the same type, length,
|
||||
+ // and that they're not too large.
|
||||
+ if (param1.isVector() != param2.isVector() ||
|
||||
+ param2.isVector() != param3.isVector() ||
|
||||
+ param1.getNominalSize() != param2.getNominalSize() ||
|
||||
+ param2.getNominalSize() != param3.getNominalSize() ||
|
||||
+ param1.getNominalSize() > 4)
|
||||
+ return TFunctionUnknown;
|
||||
+
|
||||
+ unsigned int function = TFunctionUnknown;
|
||||
+ switch (op) {
|
||||
+ case EOpFaceForward:
|
||||
+ function = TFunctionFaceForward1_1_1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ if (function == TFunctionUnknown)
|
||||
+ return TFunctionUnknown;
|
||||
+ if (param1.isVector())
|
||||
+ function += param1.getNominalSize() - 1;
|
||||
+ return static_cast<TBuiltInFunction>(function);
|
||||
+}
|
||||
+
|
||||
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
TIntermNode* root)
|
||||
{
|
||||
ASSERT(root);
|
||||
|
||||
BuiltInFunctionEmulationMarker marker(*this);
|
||||
root->traverse(&marker);
|
||||
}
|
||||
diff --git a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
|
||||
--- a/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
|
||||
+++ b/gfx/angle/src/compiler/BuiltInFunctionEmulator.h
|
||||
@@ -23,16 +23,18 @@ public:
|
||||
// Records that a function is called by the shader and might needs to be
|
||||
// emulated. If the function's group is not in mFunctionGroupFilter, this
|
||||
// becomes an no-op.
|
||||
// Returns true if the function call needs to be replaced with an emulated
|
||||
// one.
|
||||
bool SetFunctionCalled(TOperator op, const TType& param);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
+ bool SetFunctionCalled(
|
||||
+ TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
// Output function emulation definition. This should be before any other
|
||||
// shader source.
|
||||
void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
|
||||
|
||||
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
|
||||
|
||||
void Cleanup();
|
||||
@@ -55,16 +57,21 @@ private:
|
||||
TFunctionDistance3_3, // vec3 distance(vec3, vec3);
|
||||
TFunctionDistance4_4, // vec4 distance(vec4, vec4);
|
||||
|
||||
TFunctionDot1_1, // float dot(float, float);
|
||||
TFunctionDot2_2, // vec2 dot(vec2, vec2);
|
||||
TFunctionDot3_3, // vec3 dot(vec3, vec3);
|
||||
TFunctionDot4_4, // vec4 dot(vec4, vec4);
|
||||
|
||||
+ TFunctionFaceForward1_1_1, // float faceforward(float, float, float);
|
||||
+ TFunctionFaceForward2_2_2, // vec2 faceforward(vec2, vec2, vec2);
|
||||
+ TFunctionFaceForward3_3_3, // vec3 faceforward(vec3, vec3, vec3);
|
||||
+ TFunctionFaceForward4_4_4, // vec4 faceforward(vec4, vec4, vec4);
|
||||
+
|
||||
TFunctionLength1, // float length(float);
|
||||
TFunctionLength2, // float length(vec2);
|
||||
TFunctionLength3, // float length(vec3);
|
||||
TFunctionLength4, // float length(vec4);
|
||||
|
||||
TFunctionNormalize1, // float normalize(float);
|
||||
TFunctionNormalize2, // vec2 normalize(vec2);
|
||||
TFunctionNormalize3, // vec3 normalize(vec3);
|
||||
@@ -76,16 +83,18 @@ private:
|
||||
TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
|
||||
|
||||
TFunctionUnknown
|
||||
};
|
||||
|
||||
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
+ TBuiltInFunction IdentifyFunction(
|
||||
+ TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
bool SetFunctionCalled(TBuiltInFunction function);
|
||||
|
||||
std::vector<TBuiltInFunction> mFunctions;
|
||||
|
||||
const bool* mFunctionMask; // a boolean flag for each function.
|
||||
const char** mFunctionSource;
|
||||
};
|
@ -31,6 +31,12 @@ const char* kFunctionEmulationVertexSource[] = {
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
"#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
"#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
"#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
@ -63,6 +69,12 @@ const char* kFunctionEmulationFragmentSource[] = {
|
||||
"#error no emulation for dot(vec3, vec3)",
|
||||
"#error no emulation for dot(vec4, vec4)",
|
||||
|
||||
// |faceforward(N, I, Nref)| is |dot(NRef, I) < 0 ? N : -N|
|
||||
"#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))",
|
||||
"#error no emulation for faceforward(vec2, vec2, vec2)",
|
||||
"#error no emulation for faceforward(vec3, vec3, vec3)",
|
||||
"#error no emulation for faceforward(vec4, vec4, vec4)",
|
||||
|
||||
"#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
|
||||
"#error no emulation for length(vec2)",
|
||||
"#error no emulation for length(vec3)",
|
||||
@ -94,6 +106,10 @@ const bool kFunctionEmulationVertexMask[] = {
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
@ -120,6 +136,10 @@ const bool kFunctionEmulationVertexMask[] = {
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
@ -151,6 +171,10 @@ const bool kFunctionEmulationFragmentMask[] = {
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
true, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
true, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
@ -177,6 +201,10 @@ const bool kFunctionEmulationFragmentMask[] = {
|
||||
false, // TFunctionDot2_2
|
||||
false, // TFunctionDot3_3
|
||||
false, // TFunctionDot4_4
|
||||
false, // TFunctionFaceForward1_1_1
|
||||
false, // TFunctionFaceForward2_2_2
|
||||
false, // TFunctionFaceForward3_3_3
|
||||
false, // TFunctionFaceForward4_4_4
|
||||
false, // TFunctionLength1
|
||||
false, // TFunctionLength2
|
||||
false, // TFunctionLength3
|
||||
@ -244,15 +272,27 @@ public:
|
||||
return true;
|
||||
};
|
||||
const TIntermSequence& sequence = node->getSequence();
|
||||
// Right now we only handle built-in functions with two parameters.
|
||||
if (sequence.size() != 2)
|
||||
bool needToEmulate = false;
|
||||
|
||||
if (sequence.size() == 2) {
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
} else if (sequence.size() == 3) {
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
TIntermTyped* param3 = sequence[2]->getAsTyped();
|
||||
if (!param1 || !param2 || !param3)
|
||||
return true;
|
||||
needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType(), param3->getType());
|
||||
} else {
|
||||
return true;
|
||||
TIntermTyped* param1 = sequence[0]->getAsTyped();
|
||||
TIntermTyped* param2 = sequence[1]->getAsTyped();
|
||||
if (!param1 || !param2)
|
||||
return true;
|
||||
bool needToEmulate = mEmulator.SetFunctionCalled(
|
||||
node->getOp(), param1->getType(), param2->getType());
|
||||
}
|
||||
|
||||
if (needToEmulate)
|
||||
node->setUseEmulatedFunction();
|
||||
}
|
||||
@ -290,6 +330,13 @@ bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
{
|
||||
TBuiltInFunction function = IdentifyFunction(op, param1, param2, param3);
|
||||
return SetFunctionCalled(function);
|
||||
}
|
||||
|
||||
bool BuiltInFunctionEmulator::SetFunctionCalled(
|
||||
BuiltInFunctionEmulator::TBuiltInFunction function) {
|
||||
if (function == TFunctionUnknown || mFunctionMask[function] == false)
|
||||
@ -382,6 +429,34 @@ BuiltInFunctionEmulator::IdentifyFunction(
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
BuiltInFunctionEmulator::TBuiltInFunction
|
||||
BuiltInFunctionEmulator::IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3)
|
||||
{
|
||||
// Check that all params have the same type, length,
|
||||
// and that they're not too large.
|
||||
if (param1.isVector() != param2.isVector() ||
|
||||
param2.isVector() != param3.isVector() ||
|
||||
param1.getNominalSize() != param2.getNominalSize() ||
|
||||
param2.getNominalSize() != param3.getNominalSize() ||
|
||||
param1.getNominalSize() > 4)
|
||||
return TFunctionUnknown;
|
||||
|
||||
unsigned int function = TFunctionUnknown;
|
||||
switch (op) {
|
||||
case EOpFaceForward:
|
||||
function = TFunctionFaceForward1_1_1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (function == TFunctionUnknown)
|
||||
return TFunctionUnknown;
|
||||
if (param1.isVector())
|
||||
function += param1.getNominalSize() - 1;
|
||||
return static_cast<TBuiltInFunction>(function);
|
||||
}
|
||||
|
||||
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
|
||||
TIntermNode* root)
|
||||
{
|
||||
|
@ -28,6 +28,8 @@ public:
|
||||
bool SetFunctionCalled(TOperator op, const TType& param);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
bool SetFunctionCalled(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
// Output function emulation definition. This should be before any other
|
||||
// shader source.
|
||||
@ -60,6 +62,11 @@ private:
|
||||
TFunctionDot3_3, // vec3 dot(vec3, vec3);
|
||||
TFunctionDot4_4, // vec4 dot(vec4, vec4);
|
||||
|
||||
TFunctionFaceForward1_1_1, // float faceforward(float, float, float);
|
||||
TFunctionFaceForward2_2_2, // vec2 faceforward(vec2, vec2, vec2);
|
||||
TFunctionFaceForward3_3_3, // vec3 faceforward(vec3, vec3, vec3);
|
||||
TFunctionFaceForward4_4_4, // vec4 faceforward(vec4, vec4, vec4);
|
||||
|
||||
TFunctionLength1, // float length(float);
|
||||
TFunctionLength2, // float length(vec2);
|
||||
TFunctionLength3, // float length(vec3);
|
||||
@ -81,6 +88,8 @@ private:
|
||||
TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2);
|
||||
TBuiltInFunction IdentifyFunction(
|
||||
TOperator op, const TType& param1, const TType& param2, const TType& param3);
|
||||
|
||||
bool SetFunctionCalled(TBuiltInFunction function);
|
||||
|
||||
|
@ -524,7 +524,15 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
|
||||
}
|
||||
|
||||
nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
|
||||
// XXX: Implement this.
|
||||
if (mGeckoContentController) {
|
||||
MonitorAutoLock monitor(mMonitor);
|
||||
|
||||
gfx::Point point = WidgetSpaceToCompensatedViewportSpace(
|
||||
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
|
||||
mFrameMetrics.mResolution.width);
|
||||
mGeckoContentController->HandleSingleTap(nsIntPoint(NS_lround(point.x), NS_lround(point.y)));
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
@ -989,6 +997,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
// we get a larger displayport. This is very bad because we're wasting a
|
||||
// paint and not initializating the displayport correctly.
|
||||
RequestContentRepaint();
|
||||
|
||||
mState = NOTHING;
|
||||
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
|
||||
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
|
||||
SetPageRect(mFrameMetrics.mCSSContentRect);
|
||||
|
@ -31,6 +31,13 @@ public:
|
||||
*/
|
||||
virtual void HandleDoubleTap(const nsIntPoint& aPoint) = 0;
|
||||
|
||||
/**
|
||||
* Requests handling a single tap. |aPoint| is in CSS pixels, relative to the
|
||||
* current scroll offset. This should simulate and send to content a mouse
|
||||
* button down, then mouse button up at |aPoint|.
|
||||
*/
|
||||
virtual void HandleSingleTap(const nsIntPoint& aPoint) = 0;
|
||||
|
||||
GeckoContentController() {}
|
||||
virtual ~GeckoContentController() {}
|
||||
};
|
||||
|
@ -3273,11 +3273,80 @@ ShouldPreserveJITCode(JSCompartment *c, int64_t currentTime)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct CompartmentCheckTracer : public JSTracer
|
||||
{
|
||||
Cell *src;
|
||||
JSGCTraceKind srcKind;
|
||||
JSCompartment *compartment;
|
||||
};
|
||||
|
||||
static bool
|
||||
InCrossCompartmentMap(JSObject *src, Cell *dst, JSGCTraceKind dstKind)
|
||||
{
|
||||
JSCompartment *srccomp = src->compartment();
|
||||
|
||||
if (dstKind == JSTRACE_OBJECT) {
|
||||
Value key = ObjectValue(*static_cast<JSObject *>(dst));
|
||||
WrapperMap::Ptr p = srccomp->crossCompartmentWrappers.lookup(key);
|
||||
if (*p->value.unsafeGet() == ObjectValue(*src))
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the cross-compartment edge is caused by the debugger, then we don't
|
||||
* know the right hashtable key, so we have to iterate.
|
||||
*/
|
||||
for (WrapperMap::Enum e(srccomp->crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
if (e.front().key.wrapped == dst && ToMarkable(e.front().value) == src)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
CheckCompartmentCallback(JSTracer *trcArg, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
CompartmentCheckTracer *trc = static_cast<CompartmentCheckTracer *>(trcArg);
|
||||
Cell *thing = (Cell *)*thingp;
|
||||
JS_ASSERT(thing->compartment() == trc->compartment ||
|
||||
thing->compartment() == trc->runtime->atomsCompartment ||
|
||||
(trc->srcKind == JSTRACE_OBJECT &&
|
||||
InCrossCompartmentMap((JSObject *)trc->src, thing, kind)));
|
||||
}
|
||||
|
||||
static void
|
||||
CheckForCompartmentMismatches(JSRuntime *rt)
|
||||
{
|
||||
if (rt->gcDisableStrictProxyCheckingCount)
|
||||
return;
|
||||
|
||||
CompartmentCheckTracer trc;
|
||||
JS_TracerInit(&trc, rt, CheckCompartmentCallback);
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
trc.compartment = c;
|
||||
for (size_t thingKind = 0; thingKind < FINALIZE_LAST; thingKind++) {
|
||||
for (CellIterUnderGC i(c, AllocKind(thingKind)); !i.done(); i.next()) {
|
||||
trc.src = i.getCell();
|
||||
trc.srcKind = MapAllocToTraceKind(AllocKind(thingKind));
|
||||
JS_TraceChildren(&trc, trc.src, trc.srcKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
BeginMarkPhase(JSRuntime *rt)
|
||||
{
|
||||
int64_t currentTime = PRMJ_Now();
|
||||
|
||||
#ifdef DEBUG
|
||||
CheckForCompartmentMismatches(rt);
|
||||
#endif
|
||||
|
||||
rt->gcIsFull = true;
|
||||
DebugOnly<bool> any = false;
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
|
@ -2063,6 +2063,9 @@ TypeCompartment::newTypeObject(JSContext *cx, JSScript *script,
|
||||
JSProtoKey key, JSObject *proto_, bool unknown,
|
||||
bool isDOM)
|
||||
{
|
||||
JS_ASSERT_IF(script, cx->compartment == script->compartment());
|
||||
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
TypeObject *object = gc::NewGCThing<TypeObject>(cx, gc::FINALIZE_TYPE_OBJECT, sizeof(TypeObject));
|
||||
if (!object)
|
||||
@ -5579,6 +5582,8 @@ JSObject::shouldSplicePrototype(JSContext *cx)
|
||||
bool
|
||||
JSObject::splicePrototype(JSContext *cx, JSObject *proto_)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
RootedObject self(cx, this);
|
||||
|
||||
@ -5639,6 +5644,7 @@ TypeObject *
|
||||
JSObject::makeLazyType(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(hasLazyType());
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
RootedObject self(cx, this);
|
||||
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
|
||||
@ -5749,6 +5755,8 @@ JSObject::setNewTypeUnknown(JSContext *cx)
|
||||
TypeObject *
|
||||
JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
|
||||
TypeObjectSet &table = cx->compartment->newTypeObjects;
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
@ -5837,6 +5845,9 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
|
||||
TypeObject *
|
||||
JSCompartment::getLazyType(JSContext *cx, JSObject *proto_)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == this);
|
||||
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
|
||||
|
||||
RootedObject proto(cx, proto_);
|
||||
MaybeCheckStackRoots(cx);
|
||||
|
||||
|
@ -2660,6 +2660,9 @@ bool
|
||||
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
|
||||
TradeGutsReserved &reserved)
|
||||
{
|
||||
JS_ASSERT(a->compartment() == b->compartment());
|
||||
AutoCompartment ac(cx, a);
|
||||
|
||||
/*
|
||||
* When performing multiple swaps between objects which may have different
|
||||
* numbers of fixed slots, we reserve all space ahead of time so that the
|
||||
@ -2898,53 +2901,19 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
b->type_ = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this method with extreme caution. It trades the guts of two objects and updates
|
||||
* scope ownership. This operation is not thread-safe, just as fast array to slow array
|
||||
* transitions are inherently not thread-safe. Don't perform a swap operation on objects
|
||||
* shared across threads or, or bad things will happen. You have been warned.
|
||||
*/
|
||||
/* Use this method with extreme caution. It trades the guts of two objects. */
|
||||
bool
|
||||
JSObject::swap(JSContext *cx, JSObject *other)
|
||||
{
|
||||
// Ensure swap doesn't cause a finalizer to not be run.
|
||||
JS_ASSERT(IsBackgroundFinalized(getAllocKind()) ==
|
||||
IsBackgroundFinalized(other->getAllocKind()));
|
||||
JS_ASSERT(compartment() == other->compartment());
|
||||
|
||||
if (this->compartment() == other->compartment()) {
|
||||
TradeGutsReserved reserved(cx);
|
||||
if (!ReserveForTradeGuts(cx, this, other, reserved))
|
||||
return false;
|
||||
TradeGuts(cx, this, other, reserved);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *thisClone;
|
||||
JSObject *otherClone;
|
||||
{
|
||||
AutoCompartment ac(cx, other);
|
||||
thisClone = JS_CloneObject(cx, this, other->getProto(), other->getParent());
|
||||
if (!thisClone || !JS_CopyPropertiesFrom(cx, thisClone, this))
|
||||
return false;
|
||||
}
|
||||
{
|
||||
AutoCompartment ac(cx, this);
|
||||
otherClone = JS_CloneObject(cx, other, other->getProto(), other->getParent());
|
||||
if (!otherClone || !JS_CopyPropertiesFrom(cx, otherClone, other))
|
||||
return false;
|
||||
}
|
||||
|
||||
TradeGutsReserved reservedThis(cx);
|
||||
TradeGutsReserved reservedOther(cx);
|
||||
|
||||
if (!ReserveForTradeGuts(cx, this, otherClone, reservedThis) ||
|
||||
!ReserveForTradeGuts(cx, other, thisClone, reservedOther)) {
|
||||
TradeGutsReserved reserved(cx);
|
||||
if (!ReserveForTradeGuts(cx, this, other, reserved))
|
||||
return false;
|
||||
}
|
||||
|
||||
TradeGuts(cx, this, otherClone, reservedThis);
|
||||
TradeGuts(cx, other, thisClone, reservedOther);
|
||||
|
||||
TradeGuts(cx, this, other, reserved);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -663,6 +663,7 @@ JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
|
||||
inline js::types::TypeObject *
|
||||
JSObject::getType(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == compartment());
|
||||
if (hasLazyType())
|
||||
return makeLazyType(cx);
|
||||
return type_;
|
||||
@ -672,6 +673,7 @@ JSObject::getType(JSContext *cx)
|
||||
JSObject::clearType(JSContext *cx, js::HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(!obj->hasSingletonType());
|
||||
JS_ASSERT(cx->compartment == obj->compartment());
|
||||
|
||||
js::types::TypeObject *type = cx->compartment->getEmptyType(cx);
|
||||
if (!type)
|
||||
@ -692,6 +694,7 @@ JSObject::setType(js::types::TypeObject *newType)
|
||||
JS_ASSERT_IF(hasSpecialEquality(),
|
||||
newType->hasAnyFlags(js::types::OBJECT_FLAG_SPECIAL_EQUALITY));
|
||||
JS_ASSERT(!hasSingletonType());
|
||||
JS_ASSERT(compartment() == newType->compartment());
|
||||
type_ = newType;
|
||||
}
|
||||
|
||||
@ -824,6 +827,7 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind,
|
||||
JS_ASSERT(shape && type);
|
||||
JS_ASSERT(!!dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()) == !!slots);
|
||||
JS_ASSERT(js::gc::GetGCKindSlots(kind, shape->getObjectClass()) == shape->numFixedSlots());
|
||||
JS_ASSERT(cx->compartment == type->compartment());
|
||||
|
||||
JSObject *obj = js_NewGCObject(cx, kind);
|
||||
if (!obj)
|
||||
@ -852,6 +856,7 @@ JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
|
||||
{
|
||||
JS_ASSERT(shape && type);
|
||||
JS_ASSERT(shape->getObjectClass() == &js::ArrayClass);
|
||||
JS_ASSERT(cx->compartment == type->compartment());
|
||||
|
||||
/*
|
||||
* Dense arrays are non-native, and never have properties to store.
|
||||
|
@ -3059,6 +3059,7 @@ js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_,
|
||||
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
|
||||
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
|
||||
JS_ASSERT_IF(construct, cx->compartment == construct->compartment());
|
||||
JS_ASSERT_IF(call && cx->compartment != call->compartment(), priv.get() == ObjectValue(*call));
|
||||
bool fun = call || construct;
|
||||
Class *clasp;
|
||||
if (fun)
|
||||
|
@ -928,6 +928,7 @@ JSObject::rollbackProperties(JSContext *cx, uint32_t slotSpan)
|
||||
Shape *
|
||||
JSObject::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *newShape)
|
||||
{
|
||||
JS_ASSERT(cx->compartment == oldShape->compartment());
|
||||
JS_ASSERT_IF(oldShape != lastProperty(),
|
||||
inDictionaryMode() &&
|
||||
nativeLookupNoAllocation(oldShape->propidRef()) == oldShape);
|
||||
@ -1202,6 +1203,9 @@ InitialShapeEntry::match(const InitialShapeEntry &key, const Lookup &lookup)
|
||||
EmptyShape::getInitialShape(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent,
|
||||
AllocKind kind, uint32_t objectFlags)
|
||||
{
|
||||
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
|
||||
JS_ASSERT_IF(parent, cx->compartment == parent->compartment());
|
||||
|
||||
InitialShapeSet &table = cx->compartment->initialShapes;
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
|
@ -531,6 +531,8 @@ ContextStack::currentScript(jsbytecode **ppc) const
|
||||
if (fp->beginsIonActivation()) {
|
||||
JSScript *script = NULL;
|
||||
ion::GetPcScript(cx_, &script, ppc);
|
||||
if (script->compartment() != cx_->compartment)
|
||||
return NULL;
|
||||
return script;
|
||||
}
|
||||
#endif
|
||||
|
@ -511,6 +511,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void HandleSingleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
|
||||
{
|
||||
if (MessageLoop::current() != mUILoop) {
|
||||
// We have to send this message from the "UI thread" (main
|
||||
// thread).
|
||||
mUILoop->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
|
||||
aPoint));
|
||||
return;
|
||||
}
|
||||
if (mRenderFrame) {
|
||||
TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
|
||||
browser->HandleSingleTap(aPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearRenderFrame() { mRenderFrame = nullptr; }
|
||||
|
||||
private:
|
||||
|
@ -4,7 +4,7 @@ package @ANDROID_PACKAGE_NAME@.tests;
|
||||
import @ANDROID_PACKAGE_NAME@.*;
|
||||
|
||||
abstract class PixelTest extends BaseTest {
|
||||
private static final long PAINT_CLEAR_DELAY = 1000; // milliseconds
|
||||
private static final long PAINT_CLEAR_DELAY = 3000; // milliseconds
|
||||
|
||||
protected final PaintedSurface loadAndGetPainted(String url) {
|
||||
Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
|
||||
|
Loading…
Reference in New Issue
Block a user