Merge the last green PGO changeset from mozilla-inbound to mozilla-central; a=merge

This commit is contained in:
Ehsan Akhgari 2012-04-20 13:10:19 -04:00
Родитель 9753fe198f 969d9ce796
Коммит e6273ad5e1
160 изменённых файлов: 11374 добавлений и 11061 удалений

Просмотреть файл

@ -380,6 +380,9 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 4194304);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
#endif
@ -430,6 +433,9 @@ pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://b
pref("dom.sms.enabled", true);
pref("dom.sms.whitelist", "file://,http://homescreen.gaiamobile.org,http://sms.gaiamobile.org");
// Temporary permission hack for WebMobileConnection
pref("dom.mobileconnection.whitelist", "http://homescreen.gaiamobile.org");
// Temporary permission hack for WebContacts
pref("dom.mozContacts.enabled", true);
pref("dom.mozContacts.whitelist", "http://dialer.gaiamobile.org,http://sms.gaiamobile.org");

Просмотреть файл

@ -411,8 +411,11 @@
@BINPATH@/components/nsFilePicker.js
@BINPATH@/components/nsFilePicker.manifest
#ifdef MOZ_B2G_RIL
@BINPATH@/components/NetworkManager.manifest
@BINPATH@/components/NetworkManager.js
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/RILContentHelper.js
@BINPATH@/components/SmsDatabaseService.manifest
@BINPATH@/components/SmsDatabaseService.js
@BINPATH@/components/WifiWorker.js

Просмотреть файл

@ -775,6 +775,12 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 41943040);
// Maximum size of the sqlite3 cache for lookups, in bytes
pref("urlclassifier.lookupcachemax", 1048576);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");

Просмотреть файл

@ -9,7 +9,7 @@ const Cu = Components.utils;
const kIMig = Ci.nsIBrowserProfileMigrator;
const kIPStartup = Ci.nsIProfileStartup;
Cu.import("resource://gre/modules/MigrationUtils.jsm");
Cu.import("resource:///modules/MigrationUtils.jsm");
var MigrationWizard = {
_source: "", // Source Profile Migrator ContractID suffix

Просмотреть файл

@ -10,7 +10,7 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/MigrationUtils.jsm");
Cu.import("resource:///modules/MigrationUtils.jsm");
function ProfileMigrator() {
}

Просмотреть файл

@ -40,7 +40,7 @@
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/MigrationUtils.jsm");
Components.utils.import("resource:///modules/MigrationUtils.jsm");
var PlacesOrganizer = {
_places: null,

Просмотреть файл

@ -400,6 +400,7 @@
#ifdef MOZ_B2G_RIL
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/RILContentHelper.js
@BINPATH@/components/SmsDatabaseService.manifest
@BINPATH@/components/SmsDatabaseService.js
@BINPATH@/components/WifiWorker.js

Просмотреть файл

@ -1,3 +1,4 @@
collection.addons.label = Add-ons
collection.bookmarks.label = Bookmarks
collection.history.label = History
collection.passwords.label = Passwords

Просмотреть файл

@ -785,7 +785,7 @@ WebGLContext::GetContextAttributes(jsval *aResult)
NULL, NULL, JSPROP_ENUMERATE) ||
!JS_DefineProperty(cx, obj, "stencil", cf.stencil > 0 ? JSVAL_TRUE : JSVAL_FALSE,
NULL, NULL, JSPROP_ENUMERATE) ||
!JS_DefineProperty(cx, obj, "antialias", cf.samples > 0 ? JSVAL_TRUE : JSVAL_FALSE,
!JS_DefineProperty(cx, obj, "antialias", cf.samples > 1 ? JSVAL_TRUE : JSVAL_FALSE,
NULL, NULL, JSPROP_ENUMERATE) ||
!JS_DefineProperty(cx, obj, "premultipliedAlpha",
mOptions.premultipliedAlpha ? JSVAL_TRUE : JSVAL_FALSE,

Просмотреть файл

@ -1933,7 +1933,19 @@ WebGLContext::GenerateMipmap(WebGLenum target)
tex->SetGeneratedMipmap();
MakeContextCurrent();
gl->fGenerateMipmap(target);
if (gl->WorkAroundDriverBugs()) {
// bug 696495 - to work around failures in the texture-mips.html test on various drivers, we
// set the minification filter before calling glGenerateMipmap. This should not carry a significant performance
// overhead so we do it unconditionally.
//
// note that the choice of GL_NEAREST_MIPMAP_NEAREST really matters. See Chromium bug 101105.
gl->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST_MIPMAP_NEAREST);
gl->fGenerateMipmap(target);
gl->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, tex->MinFilter());
} else {
gl->fGenerateMipmap(target);
}
return NS_OK;
}

Просмотреть файл

@ -1,4 +1,2 @@
conformance/glsl/misc/glsl-function-nodes.html
conformance/programs/program-test.html
conformance/textures/texture-mips.html
conformance/textures/texture-npot.html

Просмотреть файл

@ -113,7 +113,7 @@ function report(testName, success) {
]]></script>
<script type="text/javascript"><![CDATA[
try {
eval("let (x=1) (x)");
let (x=1) (x);
var success = false;
}
catch (e) { success = true; }

Просмотреть файл

@ -78,6 +78,7 @@
#include "nsIWebNavigation.h"
#include "mozilla/ClearOnShutdown.h"
#include "Connection.h"
#include "MobileConnection.h"
#ifdef MOZ_B2G_RIL
#include "TelephonyFactory.h"
@ -195,6 +196,11 @@ Navigator::Invalidate()
mConnection = nsnull;
}
if (mMobileConnection) {
mMobileConnection->Shutdown();
mMobileConnection = nsnull;
}
#ifdef MOZ_B2G_BT
if (mBluetooth) {
mBluetooth = nsnull;
@ -1139,6 +1145,37 @@ Navigator::GetMozConnection(nsIDOMMozConnection** aConnection)
return NS_OK;
}
NS_IMETHODIMP
Navigator::GetMozMobileConnection(nsIDOMMozMobileConnection** aMobileConnection)
{
*aMobileConnection = nsnull;
if (!mMobileConnection) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
// Chrome is always allowed access, so do the permission check only
// for non-chrome pages.
if (!nsContentUtils::IsCallerChrome()) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
NS_ENSURE_TRUE(doc, NS_OK);
nsCOMPtr<nsIURI> uri;
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
if (!nsContentUtils::URIIsChromeOrInPref(uri, "dom.mobileconnection.whitelist")) {
return NS_OK;
}
}
mMobileConnection = new network::MobileConnection();
mMobileConnection->Init(window);
}
NS_ADDREF(*aMobileConnection = mMobileConnection);
return NS_OK;
}
#ifdef MOZ_B2G_BT
//*****************************************************************************
// nsNavigator::nsIDOMNavigatorBluetooth

Просмотреть файл

@ -87,6 +87,7 @@ class SmsManager;
namespace network {
class Connection;
class MobileConnection;
} // namespace Connection;
namespace power {
@ -158,6 +159,7 @@ private:
nsCOMPtr<nsIDOMTelephony> mTelephony;
#endif
nsRefPtr<network::Connection> mConnection;
nsRefPtr<network::MobileConnection> mMobileConnection;
#ifdef MOZ_B2G_BT
nsCOMPtr<nsIDOMBluetoothAdapter> mBluetooth;
#endif

Просмотреть файл

@ -518,6 +518,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "nsIDOMSmsCursor.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMConnection.h"
#include "nsIDOMMobileConnection.h"
#include "mozilla/dom/network/Utils.h"
#ifdef MOZ_B2G_RIL
@ -1458,6 +1459,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(MozConnection, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozMobileConnection, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
@ -4075,6 +4079,11 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozMobileConnection, nsIDOMMozMobileConnection)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileConnection)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
DOM_CLASSINFO_MAP_END

Просмотреть файл

@ -436,6 +436,7 @@ DOMCI_CLASS(MozSmsFilter)
DOMCI_CLASS(MozSmsCursor)
DOMCI_CLASS(MozConnection)
DOMCI_CLASS(MozMobileConnection)
// @font-face in CSS
DOMCI_CLASS(CSSFontFaceRule)

Просмотреть файл

@ -2317,3 +2317,26 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, jsval* aPlugins)
*aPlugins = OBJECT_TO_JSVAL(jsPlugins);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_FAILURE;
}
presShell->SetScrollPositionClampingScrollPortSize(
nsPresContext::CSSPixelsToAppUnits(aWidth),
nsPresContext::CSSPixelsToAppUnits(aHeight));
return NS_OK;
}

Просмотреть файл

@ -70,7 +70,7 @@ interface nsIDOMFile;
interface nsIFile;
interface nsIDOMTouch;
[scriptable, uuid(c7f303a1-4f7b-4d38-a192-c3f0e25dadb1)]
[scriptable, uuid(66a68858-df38-40e1-a792-fda04ebcc084)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1110,4 +1110,12 @@ interface nsIDOMWindowUtils : nsISupports {
*/
[implicit_jscontext]
readonly attribute jsval plugins;
/**
* Set the scrollport size for the purposes of clamping scroll positions for
* the root scroll frame of this document to be (aWidth,aHeight) in CSS pixels.
*
* The caller of this method must have UniversalXPConnect privileges.
*/
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
};

Просмотреть файл

@ -48,6 +48,8 @@ include $(topsrcdir)/dom/dom-config.mk
XPIDLSRCS = \
nsIDOMNavigatorNetwork.idl \
nsIDOMConnection.idl \
nsIDOMMobileConnection.idl \
nsIMobileConnectionProvider.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,105 @@
/* 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 "nsIDOMEventTarget.idl"
interface nsIDOMEventListener;
interface nsIDOMDOMRequest;
interface nsIDOMMozMobileConnectionInfo;
[scriptable, uuid(ba2be619-fed6-4652-865a-c61f88ffeaa8)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
/**
* Indicates the state of the device's ICC card.
*
* Possible values: null, 'absent', 'pinRequired', 'pukRequired',
* 'networkLocked', 'ready'.
*/
readonly attribute DOMString cardState;
/**
* Information about the voice connection.
*/
readonly attribute nsIDOMMozMobileConnectionInfo voice;
/**
* Information about the data connection.
*/
readonly attribute nsIDOMMozMobileConnectionInfo data;
/**
* Search for available networks.
*
* If successful, the request result will be an array of operator names.
*/
nsIDOMDOMRequest getNetworks();
/**
* The 'cardstatechange' event is notified when the 'cardState' attribute
* changes value.
*/
attribute nsIDOMEventListener oncardstatechange;
/**
* The 'voicechange' event is notified whenever the voice connection object
* changes.
*/
attribute nsIDOMEventListener onvoicechange;
/**
* The 'datachange' event is notified whenever the data connection object
* changes values.
*/
attribute nsIDOMEventListener ondatachange;
};
[scriptable, uuid(f3bb0611-5e4a-46f1-a8f5-cf592b37596e)]
interface nsIDOMMozMobileConnectionInfo : nsISupports
{
/**
* Indicates whether the device is connected to a mobile network.
*/
readonly attribute bool connected;
/**
* Indicates whether only emergency calls are possible.
*
* This flag is only relevant to voice connections and when 'connected' is
* false.
*/
readonly attribute bool emergencyCallsOnly;
/**
* Indicates whether the connection is going through a foreign operator
* (roaming) or not.
*/
readonly attribute bool roaming;
/**
* Operator name.
*/
readonly attribute DOMString operator;
/**
* Type of connection.
*
* Possible values: 'gsm', 'cdma', gprs', 'edge', 'umts', 'hsdpa', 'evdo0',
* 'evdoa', 'evdob', etc.
*/
readonly attribute DOMString type;
/**
* Signal strength in dBm, or null if no service is available.
*/
readonly attribute jsval signalStrength;
/**
* Signal strength, represented linearly as a number between 0 (weakest
* signal) and 100 (full signal).
*/
readonly attribute jsval relSignalStrength;
};

Просмотреть файл

@ -37,9 +37,11 @@
#include "nsISupports.idl"
interface nsIDOMMozConnection;
interface nsIDOMMozMobileConnection;
[scriptable, uuid(1dd6773e-30dc-419b-9766-b05458fd96c8)]
[scriptable, uuid(fb7c3429-aa2c-4ccc-948a-467c0de29fff)]
interface nsIDOMMozNavigatorNetwork : nsISupports
{
readonly attribute nsIDOMMozConnection mozConnection;
readonly attribute nsIDOMMozMobileConnection mozMobileConnection;
};

Просмотреть файл

@ -0,0 +1,23 @@
/* 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 "nsISupports.idl"
interface nsIDOMMozMobileConnectionInfo;
interface nsIDOMDOMRequest;
interface nsIDOMWindow;
/**
* XPCOM component (in the content process) that provides the mobile
* network information.
*/
[scriptable, uuid(1ecd19eb-15d4-47c0-a2cf-80cfa3b94eeb)]
interface nsIMobileConnectionProvider : nsISupports
{
readonly attribute DOMString cardState;
readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo;
readonly attribute nsIDOMMozMobileConnectionInfo dataConnectionInfo;
nsIDOMDOMRequest getNetworks(in nsIDOMWindow window);
};

Просмотреть файл

@ -57,6 +57,7 @@ EXPORTS_mozilla/dom/network = \
CPPSRCS = \
Connection.cpp \
MobileConnection.cpp \
Utils.cpp \
$(NULL)

Просмотреть файл

@ -0,0 +1,188 @@
/* 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 "MobileConnection.h"
#include "nsIDOMDOMRequest.h"
#include "nsIDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
#define VOICECHANGE_EVENTNAME NS_LITERAL_STRING("voicechange")
#define DATACHANGE_EVENTNAME NS_LITERAL_STRING("datachange")
#define CARDSTATECHANGE_EVENTNAME NS_LITERAL_STRING("cardstatechange")
DOMCI_DATA(MozMobileConnection, mozilla::dom::network::MobileConnection)
namespace mozilla {
namespace dom {
namespace network {
const char* kVoiceChangedTopic = "mobile-connection-voice-changed";
const char* kDataChangedTopic = "mobile-connection-data-changed";
const char* kCardStateChangedTopic = "mobile-connection-cardstate-changed";
NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(cardstatechange)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(voicechange)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(datachange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(cardstatechange)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(voicechange)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(datachange)
tmp->mProvider = nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozMobileConnection)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
MobileConnection::MobileConnection()
{
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
if (!mProvider) {
NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
}
}
void
MobileConnection::Init(nsPIDOMWindow* aWindow)
{
BindToOwner(aWindow);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
NS_WARNING("Could not acquire nsIObserverService!");
return;
}
obs->AddObserver(this, kVoiceChangedTopic, false);
obs->AddObserver(this, kDataChangedTopic, false);
obs->AddObserver(this, kCardStateChangedTopic, false);
}
void
MobileConnection::Shutdown()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
NS_WARNING("Could not acquire nsIObserverService!");
return;
}
obs->RemoveObserver(this, kVoiceChangedTopic);
obs->RemoveObserver(this, kDataChangedTopic);
obs->RemoveObserver(this, kCardStateChangedTopic);
}
// nsIObserver
NS_IMETHODIMP
MobileConnection::Observe(nsISupports* aSubject,
const char* aTopic,
const PRUnichar* aData)
{
if (!strcmp(aTopic, kVoiceChangedTopic)) {
InternalDispatchEvent(VOICECHANGE_EVENTNAME);
return NS_OK;
}
if (!strcmp(aTopic, kDataChangedTopic)) {
InternalDispatchEvent(DATACHANGE_EVENTNAME);
return NS_OK;
}
if (!strcmp(aTopic, kCardStateChangedTopic)) {
InternalDispatchEvent(CARDSTATECHANGE_EVENTNAME);
return NS_OK;
}
MOZ_NOT_REACHED("Unknown observer topic!");
return NS_OK;
}
// nsIDOMMozMobileConnection
NS_IMETHODIMP
MobileConnection::GetCardState(nsAString& cardState)
{
if (!mProvider) {
cardState.SetIsVoid(true);
return NS_OK;
}
return mProvider->GetCardState(cardState);
}
NS_IMETHODIMP
MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
{
if (!mProvider) {
*voice = nsnull;
return NS_OK;
}
return mProvider->GetVoiceConnectionInfo(voice);
}
NS_IMETHODIMP
MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
{
if (!mProvider) {
*data = nsnull;
return NS_OK;
}
return mProvider->GetDataConnectionInfo(data);
}
NS_IMETHODIMP
MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
{
*request = nsnull;
if (!mProvider) {
return NS_ERROR_FAILURE;
}
return mProvider->GetNetworks(GetOwner(), request);
}
nsresult
MobileConnection::InternalDispatchEvent(const nsAString& aType)
{
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
nsresult rv = event->InitEvent(aType, false, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = event->SetTrusted(true);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
rv = DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(MobileConnection, cardstatechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
} // namespace network
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,51 @@
/* 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 mozilla_dom_network_MobileConnection_h
#define mozilla_dom_network_MobileConnection_h
#include "nsIObserver.h"
#include "nsIDOMMobileConnection.h"
#include "nsIMobileConnectionProvider.h"
#include "nsDOMEventTargetHelper.h"
#include "nsCycleCollectionParticipant.h"
namespace mozilla {
namespace dom {
namespace network {
class MobileConnection : public nsDOMEventTargetHelper
, public nsIDOMMozMobileConnection
, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSIDOMMOZMOBILECONNECTION
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
MobileConnection();
void Init(nsPIDOMWindow *aWindow);
void Shutdown();
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileConnection,
nsDOMEventTargetHelper)
private:
nsCOMPtr<nsIMobileConnectionProvider> mProvider;
nsresult InternalDispatchEvent(const nsAString& aType);
NS_DECL_EVENT_HANDLER(cardstatechange)
NS_DECL_EVENT_HANDLER(voicechange)
NS_DECL_EVENT_HANDLER(datachange)
};
} // namespace network
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_network_MobileConnection_h

Просмотреть файл

@ -53,6 +53,7 @@ include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
EXPORTS = \
ANPKeyCodes.h \
android_npapi.h \
$(NULL)

Просмотреть файл

@ -125,7 +125,6 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#ifdef MOZ_WIDGET_ANDROID
#include "ANPBase.h"
#include "android_npapi.h"
#include "AndroidBridge.h"
#include "AndroidMediaLayer.h"
using namespace mozilla::dom;
@ -2717,33 +2716,13 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
{
const nsKeyEvent& keyEvent = static_cast<const nsKeyEvent&>(anEvent);
LOG("Firing NS_KEY_EVENT %d %d\n", keyEvent.keyCode, keyEvent.charCode);
int modifiers = 0;
if (keyEvent.isShift)
modifiers |= kShift_ANPKeyModifier;
if (keyEvent.isAlt)
modifiers |= kAlt_ANPKeyModifier;
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kKey_ANPEventType;
event.data.key.nativeCode = keyEvent.keyCode;
event.data.key.virtualCode = keyEvent.charCode;
event.data.key.modifiers = modifiers;
event.data.key.repeatCount = 0;
event.data.key.unichar = 0;
switch (anEvent.message)
{
case NS_KEY_DOWN:
event.data.key.action = kDown_ANPKeyAction;
mInstance->HandleEvent(&event, nsnull);
break;
case NS_KEY_UP:
event.data.key.action = kUp_ANPKeyAction;
mInstance->HandleEvent(&event, nsnull);
break;
}
// pluginEvent is initialized by nsWindow::InitKeyEvent().
ANPEvent* pluginEvent = reinterpret_cast<ANPEvent*>(keyEvent.pluginEvent);
if (pluginEvent) {
MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
mInstance->HandleEvent(pluginEvent, nsnull);
}
}
}
rv = nsEventStatus_eConsumeNoDefault;

Просмотреть файл

@ -25,6 +25,7 @@ CPPSRCS = \
XPIDLSRCS = \
nsIAudioManager.idl \
nsINetworkManager.idl \
nsIRadioInterfaceLayer.idl \
nsIWorkerHolder.idl \
$(NULL)
@ -47,8 +48,11 @@ LOCAL_INCLUDES += -I$(topsrcdir)/media/libsydneyaudio/src
endif
EXTRA_COMPONENTS = \
NetworkManager.manifest \
NetworkManager.js \
RadioInterfaceLayer.manifest \
RadioInterfaceLayer.js \
RILContentHelper.js \
$(NULL)
EXTRA_JS_MODULES = \

Просмотреть файл

@ -0,0 +1,204 @@
/* 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/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const NETWORKMANAGER_CONTRACTID = "@mozilla.org/network/manager;1";
const NETWORKMANAGER_CID =
Components.ID("{33901e46-33b8-11e1-9869-f46d04d25bcc}");
const NETWORKINTERFACE_CONTRACTID = "@mozilla.org/network/interface;1";
const NETWORKINTERFACE_CID =
Components.ID("{266c3edd-78f0-4512-8178-2d6fee2d35ee}");
const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed";
const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
const TOPIC_DEFAULT_ROUTE_CHANGED = "network-default-route-changed";
const DEBUG = false;
/**
* This component watches for network interfaces changing state and then
* adjusts routes etc. accordingly.
*/
function NetworkManager() {
this.networkInterfaces = {};
Services.obs.addObserver(this, TOPIC_INTERFACE_STATE_CHANGED, true);
debug("Starting worker.");
this.worker = new ChromeWorker("resource://gre/modules/net_worker.js");
this.worker.onmessage = function onmessage(event) {
this.handleWorkerMessage(event.data);
}.bind(this);
this.worker.onerror = function onerror(event) {
debug("Received error from worker: " + event.filename +
":" + event.lineno + ": " + event.message + "\n");
// Prevent the event from bubbling any further.
event.preventDefault();
};
}
NetworkManager.prototype = {
classID: NETWORKMANAGER_CID,
classInfo: XPCOMUtils.generateCI({classID: NETWORKMANAGER_CID,
contractID: NETWORKMANAGER_CONTRACTID,
classDescription: "Network Manager",
interfaces: [Ci.nsINetworkManager]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkManager,
Ci.nsISupportsWeakReference,
Ci.nsIObserver,
Ci.nsIWorkerHolder]),
// nsIWorkerHolder
worker: null,
// nsIObserver
observe: function observe(subject, topic, data) {
if (topic != TOPIC_INTERFACE_STATE_CHANGED) {
return;
}
let network = subject.QueryInterface(Ci.nsINetworkInterface);
debug("Network '" + network.name + "' changed state to " + network.state);
switch (network.state) {
case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
case Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTING:
this.setAndConfigureActive();
break;
}
},
// nsINetworkManager
registerNetworkInterface: function registerNetworkInterface(network) {
if (!(network instanceof Ci.nsINetworkInterface)) {
throw Components.Exception("Argument must be nsINetworkInterface.",
Cr.NS_ERROR_INVALID_ARG);
}
if (network.name in this.networkInterfaces) {
throw Components.Exception("Network with that name already registered!",
Cr.NS_ERROR_INVALID_ARG);
}
this.networkInterfaces[network.name] = network;
this.setAndConfigureActive();
Services.obs.notifyObservers(network, TOPIC_INTERFACE_REGISTERED, null);
debug("Network '" + network.name + "' registered.");
},
unregisterNetworkInterface: function unregisterNetworkInterface(network) {
if (!(network instanceof Ci.nsINetworkInterface)) {
throw Components.Exception("Argument must be nsINetworkInterface.",
Cr.NS_ERROR_INVALID_ARG);
}
if (!(network.name in this.networkInterfaces)) {
throw Components.Exception("No network with that name registered.",
Cr.NS_ERROR_INVALID_ARG);
}
delete this.networkInterfaces[network.name];
this.setAndConfigureActive();
Services.obs.notifyObservers(network, TOPIC_INTERFACE_UNREGISTERED, null);
debug("Network '" + network.name + "' unregistered.");
},
networkInterfaces: null,
_preferredNetworkType: DEFAULT_PREFERRED_NETWORK_TYPE,
get preferredNetworkType() {
return this._preferredNetworkType;
},
set preferredNetworkType(val) {
if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS].indexOf(val) == -1) {
throw "Invalid network type";
}
this._preferredNetworkType = val;
},
active: null,
_overriddenActive: null,
overrideActive: function overrideActive(network) {
this._overriddenActive = network;
this.setAndConfigureActive();
},
// Helpers
handleWorkerMessage: function handleWorkerMessage(message) {
debug("NetworkManager received message from worker: " + JSON.stringify(message));
},
/**
* Determine the active interface and configure it.
*/
setAndConfigureActive: function setAndConfigureActive() {
debug("Evaluating whether active network needs to be changed.");
if (this._overriddenActive) {
debug("We have an override for the active network: " +
this._overriddenActive.name);
// The override was just set, so reconfigure the network.
if (this.active != this._overriddenActive) {
this.active = this._overriddenActive;
this.setDefaultRouteAndDNS();
}
return;
}
// If the active network is already of the preferred type, nothing to do.
if (this.active && this.active.type == this._preferredNetworkType) {
debug("Active network is already our preferred type. Not doing anything.");
return;
}
// Find a suitable network interface to activate.
let oldActive = this.active;
this.active = null;
for each (let network in this.networkInterfaces) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
continue;
}
this.active = network;
if (network.type == this.preferredNetworkType) {
debug("Found our preferred type of network: " + network.name);
break;
}
}
if (oldActive != this.active) {
this.setDefaultRouteAndDNS();
}
},
setDefaultRouteAndDNS: function setDefaultRouteAndDNS() {
debug("Going to change route and DNS to " + this.active.name);
if (this.active.dhcp) {
this.worker.postMessage({cmd: "runDHCPAndSetDefaultRouteAndDNS",
ifname: this.active.name});
} else {
this.worker.postMessage({cmd: "setDefaultRouteAndDNS",
ifname: this.active.name});
}
},
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkManager]);
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- NetworkManager: " + s + "\n");
};
} else {
debug = function (s) {};
}

Просмотреть файл

@ -0,0 +1,3 @@
# NetworkManager.js
component {33901e46-33b8-11e1-9869-f46d04d25bcc} NetworkManager.js
contract @mozilla.org/network/manager;1 {33901e46-33b8-11e1-9869-f46d04d25bcc}

Просмотреть файл

@ -0,0 +1,153 @@
/* 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/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
var RIL = {};
Cu.import("resource://gre/modules/ril_consts.js", RIL);
const DEBUG = false; // set to true to see debug messages
const RILCONTENTHELPER_CID =
Components.ID("{472816e1-1fd6-4405-996c-806f9ea68174}");
const MOBILECONNECTIONINFO_CID =
Components.ID("{a35cfd39-2d93-4489-ac7d-396475dacb27}");
const RIL_IPC_MSG_NAMES = [
"RIL:CardStateChanged",
"RIL:VoiceInfoChanged",
"RIL:DataInfoChanged",
];
const kVoiceChangedTopic = "mobile-connection-voice-changed";
const kDataChangedTopic = "mobile-connection-data-changed";
const kCardStateChangedTopic = "mobile-connection-cardstate-changed";
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIFrameMessageManager");
function MobileConnectionInfo() {}
MobileConnectionInfo.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozMobileConnectionInfo]),
classID: MOBILECONNECTIONINFO_CID,
classInfo: XPCOMUtils.generateCI({
classID: MOBILECONNECTIONINFO_CID,
classDescription: "MobileConnectionInfo",
flags: Ci.nsIClassInfo.DOM_OBJECT,
interfaces: [Ci.nsIDOMMozMobileConnectionInfo]
}),
// nsIDOMMozMobileConnectionInfo
connected: false,
emergencyCallsOnly: false,
roaming: false,
operator: null,
type: null,
signalStrength: null,
relSignalStrength: null
};
function RILContentHelper() {
this.voiceConnectionInfo = new MobileConnectionInfo();
this.dataConnectionInfo = new MobileConnectionInfo();
for each (let msgname in RIL_IPC_MSG_NAMES) {
cpmm.addMessageListener(msgname, this);
}
Services.obs.addObserver(this, "xpcom-shutdown", false);
// Request initial state.
let radioState = cpmm.QueryInterface(Ci.nsISyncMessageSender)
.sendSyncMessage("RIL:GetRadioState")[0];
if (!radioState) {
debug("Received null radioState from chrome process.");
return;
}
this.cardState = radioState.cardState;
for (let key in radioState.voice) {
this.voiceConnectionInfo[key] = radioState.voice[key];
}
for (let key in radioState.data) {
this.dataConnectionInfo[key] = radioState.data[key];
}
}
RILContentHelper.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionProvider,
Ci.nsIRILContentHelper,
Ci.nsIObserver]),
classID: RILCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({classID: RILCONTENTHELPER_CID,
classDescription: "RILContentHelper",
interfaces: [Ci.nsIMobileConnectionProvider,
Ci.nsIRILContentHelper]}),
// nsIRILContentHelper
cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE,
voiceConnectionInfo: null,
dataConnectionInfo: null,
getNetworks: function getNetworks(window) {
//TODO bug 744344
throw Components.Exception("Not implemented", Cr.NS_ERROR_NOT_IMPLEMENTED);
},
// nsIObserver
observe: function observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
for each (let msgname in RIL_IPC_MSG_NAMES) {
cpmm.removeMessageListener(msgname, this);
}
Services.obs.removeObserver(this, "xpcom-shutdown");
cpmm = null;
}
},
// nsIFrameMessageListener
receiveMessage: function receiveMessage(msg) {
debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
switch (msg.name) {
case "RIL:CardStateChanged":
if (this.cardState != msg.json.cardState) {
this.cardState = msg.json.cardState;
Services.obs.notifyObservers(null, kCardStateChangedTopic, null);
}
break;
case "RIL:VoiceInfoChanged":
for (let key in msg.json) {
this.voiceConnectionInfo[key] = msg.json[key];
}
Services.obs.notifyObservers(null, kVoiceChangedTopic, null);
break;
case "RIL:DataInfoChanged":
for (let key in msg.json) {
this.dataConnectionInfo[key] = msg.json[key];
}
Services.obs.notifyObservers(null, kDataChangedTopic, null);
break;
}
},
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([RILContentHelper]);
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- RILContentHelper: " + s + "\n");
};
} else {
debug = function (s) {};
}

Просмотреть файл

@ -57,6 +57,7 @@ const DATACALLINFO_CID =
const nsIAudioManager = Ci.nsIAudioManager;
const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
const kSmsReceivedObserverTopic = "sms-received";
const kSmsDeliveredObserverTopic = "sms-delivered";
const DOM_SMS_DELIVERY_RECEIVED = "received";
@ -74,6 +75,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSmsDatabaseService",
"@mozilla.org/sms/rilsmsdatabaseservice;1",
"nsISmsDatabaseService");
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIFrameMessageManager");
function convertRILCallState(state) {
switch (state) {
case RIL.CALL_STATE_ACTIVE:
@ -137,21 +142,36 @@ DataCallInfo.protoptype = {
function RadioInterfaceLayer() {
debug("Starting RIL Worker");
this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
this.worker.onerror = this.onerror.bind(this);
this.worker.onmessage = this.onmessage.bind(this);
debug("Starting Worker\n");
this.radioState = {
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE,
connected: null,
roaming: null,
signalStrength: null,
bars: null,
operator: null,
type: null,
msisdn: null,
// These objects implement the nsIDOMMozMobileConnectionInfo interface,
// although the actual implementation lives in the content process.
voice: {connected: false,
emergencyCallsOnly: false,
roaming: false,
operator: null,
type: null,
signalStrength: null,
relSignalStrength: null},
data: {connected: false,
emergencyCallsOnly: false,
roaming: false,
operator: null,
type: null,
signalStrength: null,
relSignalStrength: null},
};
ppmm.addMessageListener("RIL:GetRadioState", this);
Services.obs.addObserver(this, "xpcom-shutdown", false);
this._sentSmsEnvelopes = {};
}
RadioInterfaceLayer.prototype = {
@ -165,6 +185,18 @@ RadioInterfaceLayer.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder,
Ci.nsIRadioInterfaceLayer]),
/**
* Process a message from the content process.
*/
receiveMessage: function receiveMessage(msg) {
debug("Received '" + msg.name + "' message from content process");
switch (msg.name) {
case "RIL:GetRadioState":
// This message is sync.
return this.radioState;
}
},
onerror: function onerror(event) {
debug("Got an error: " + event.filename + ":" +
event.lineno + ": " + event.message + "\n");
@ -172,16 +204,15 @@ RadioInterfaceLayer.prototype = {
},
/**
* Process the incoming message from the RIL worker:
* (1) Update the current state. This way any component that hasn't
* been listening for callbacks can easily catch up by looking at
* this.radioState.
* Process the incoming message from the RIL worker. This roughly
* works as follows:
* (1) Update local state.
* (2) Update state in related systems such as the audio.
* (3) Multiplex the message to telephone callbacks.
* (3) Multiplex the message to callbacks / listeners (typically the DOM).
*/
onmessage: function onmessage(event) {
let message = event.data;
debug("Received message: " + JSON.stringify(message));
debug("Received message from worker: " + JSON.stringify(message));
switch (message.type) {
case "callStateChange":
// This one will handle its own notifications.
@ -196,62 +227,23 @@ RadioInterfaceLayer.prototype = {
this.handleEnumerateCalls(message.calls);
break;
case "voiceregistrationstatechange":
this.updateDataConnection(message.voiceRegistrationState);
this.updateVoiceConnection(message);
break;
case "dataregistrationstatechange":
let state = message.dataRegistrationState;
this.updateDataConnection(state);
//TODO for simplicity's sake, for now we only look at
// dataRegistrationState for the radio registration state.
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
this.resetRadioState();
this.notifyRadioStateChanged();
return;
}
this.radioState.connected =
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME) ||
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
this.radioState.roaming =
this.radioState.connected &&
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
this.radioState.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
this.notifyRadioStateChanged();
this.updateDataConnection(message);
break;
case "signalstrengthchange":
//TODO GSM only?
let signalStrength = message.signalStrength.gsmSignalStrength;
if (signalStrength == 99) {
signalStrength = null;
}
this.radioState.signalStrength = signalStrength;
if (message.signalStrength.bars) {
this.radioState.bars = message.signalStrength.bars;
} else if (signalStrength != null) {
//TODO pretty sure that the bars aren't linear, but meh...
// Convert signal strength (0...31) to bars (0...4).
this.radioState.bars = Math.round(signalStrength / 7.75);
} else {
this.radioState.bars = null;
}
this.notifyRadioStateChanged();
this.handleSignalStrengthChange(message);
break;
case "operatorchange":
this.radioState.operator = message.operator.alphaLong;
this.notifyRadioStateChanged();
this.handleOperatorChange(message);
break;
case "radiostatechange":
this.radioState.radioState = message.radioState;
this.notifyRadioStateChanged();
break;
case "cardstatechange":
this.radioState.cardState = message.cardState;
if (!message.cardState || message.cardState == "absent") {
this.resetRadioState();
}
this.notifyRadioStateChanged();
ppmm.sendAsyncMessage("RIL:CardStateChange", message);
break;
case "sms-received":
this.handleSmsReceived(message);
@ -292,6 +284,34 @@ RadioInterfaceLayer.prototype = {
}
},
updateVoiceConnection: function updateVoiceConnection(state) {
let voiceInfo = this.radioState.voice;
voiceInfo.type = "gsm"; //TODO see bug 726098.
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
voiceInfo.connected = false;
voiceInfo.emergencyCallsOnly = false;
voiceInfo.roaming = false;
voiceInfo.operator = null;
voiceInfo.type = null;
voiceInfo.signalStrength = null;
voiceInfo.relSignalStrength = null;
ppmm.sendAsyncMessage("RIL:VoiceThis.RadioState.VoiceChanged",
voiceInfo);
return;
}
//TODO emergency calls
voiceInfo.connected =
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME) ||
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
voiceInfo.roaming =
voiceInfo.connected &&
(state == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
voiceInfo.type =
RIL.GECKO_RADIO_TECH[state.radioTech] || null;
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
},
_isDataEnabled: function _isDataEnabled() {
try {
return Services.prefs.getBoolPref("ril.data.enabled");
@ -325,6 +345,32 @@ RadioInterfaceLayer.prototype = {
// RILNetworkInterface will ignore this if it's already connected.
RILNetworkInterface.connect();
}
//TODO need to keep track of some of the state information, and then
// notify the content when state changes (connected, technology
// changes, etc.). This should be done in RILNetworkInterface.
},
handleSignalStrengthChange: function handleSignalStrengthChange(message) {
// TODO CDMA, EVDO, LTE, etc. (see bug 726098)
this.radioState.voice.signalStrength = message.gsmDBM;
this.radioState.voice.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", this.radioState.voice);
this.radioState.data.signalStrength = message.gsmDBM;
this.radioState.data.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", this.radioState.data);
},
handleOperatorChange: function handleOperatorChange(message) {
let operator = message.alphaLong;
if (operator != this.radioState.voice.operator) {
this.radioState.voice.operator = operator;
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", this.radioState.voice);
}
if (operator != this.radioState.data.operator) {
this.radioState.data.operator = operator;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", this.radioState.data);
}
},
/**
@ -525,18 +571,14 @@ RadioInterfaceLayer.prototype = {
[datacalls, datacalls.length]);
},
resetRadioState: function resetRadioState() {
this.radioState.connected = null;
this.radioState.roaming = null;
this.radioState.signalStrength = null;
this.radioState.bars = null;
this.radioState.operator = null;
this.radioState.type = null;
},
// nsIObserver
notifyRadioStateChanged: function notifyRadioStateChanged() {
debug("Radio state changed: " + JSON.stringify(this.radioState));
Services.obs.notifyObservers(null, "ril-radiostate-changed", null);
observe: function observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
ppmm.removeMessageListener("RIL:GetRadioState", this);
Services.obs.removeObserver(this, "xpcom-shutdown");
ppmm = null;
}
},
// nsIRadioWorker
@ -1134,26 +1176,29 @@ RadioInterfaceLayer.prototype = {
let RILNetworkInterface = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRILDataCallback]),
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface,
Ci.nsIRILDataCallback]),
// nsINetworkInterface
NETWORK_STATE_UNKNOWN: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
NETWORK_STATE_CONNECTING: Ci.nsINetworkInterface.CONNECTING,
NETWORK_STATE_CONNECTED: Ci.nsINetworkInterface.CONNECTED,
NETWORK_STATE_SUSPENDED: Ci.nsINetworkInterface.SUSPENDED,
NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInterface.DISCONNECTING,
NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInterface.DISCONNECTED,
state: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
NETWORK_TYPE_WIFI: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
NETWORK_TYPE_MOBILE: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
type: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
state: RIL.GECKO_NETWORK_STATE_UNKNOWN,
name: null,
worker: null,
cid: null,
registeredAsDataCallCallback: false,
connecting: false,
initWorker: function initWorker() {
debug("Starting net_worker.");
this.worker = new ChromeWorker("resource://gre/modules/net_worker.js");
this.worker.onerror = function onerror(event) {
debug("Received error from worker: " + event.filename +
":" + event.lineno + ": " + event.message + "\n");
// Prevent the event from bubbling any further.
event.preventDefault();
};
},
dhcp: false,
// nsIRILDataCallback
@ -1165,6 +1210,12 @@ let RILNetworkInterface = {
this.cid = cid;
this.name = interfaceName;
debug("Data call ID: " + cid + ", interface name: " + interfaceName);
if (!this.registeredAsNetworkInterface) {
let networkManager = Cc["@mozilla.org/network/manager;1"]
.getService(Ci.nsINetworkManager);
networkManager.registerNetworkInterface(this);
this.registeredAsNetworkInterface = true;
}
}
if (this.cid != cid) {
return;
@ -1174,12 +1225,9 @@ let RILNetworkInterface = {
}
this.state = callState;
if (callState == RIL.GECKO_NETWORK_STATE_CONNECTED) {
debug("Data call is connected, going to configure networking bits.");
this.worker.postMessage({cmd: "setDefaultRouteAndDNS",
ifname: this.name});
}
Services.obs.notifyObservers(this,
kNetworkInterfaceStateChangedTopic,
null);
},
receiveDataCallList: function receiveDataCallList(dataCalls, length) {
@ -1187,6 +1235,11 @@ let RILNetworkInterface = {
// Helpers
cid: null,
registeredAsDataCallCallback: false,
registeredAsNetworkInterface: false,
connecting: false,
get mRIL() {
delete this.mRIL;
return this.mRIL = Cc["@mozilla.org/telephony/system-worker-manager;1"]
@ -1206,10 +1259,6 @@ let RILNetworkInterface = {
this.registeredAsDataCallCallback = true;
}
if (!this.worker) {
this.initWorker();
}
let apn, user, passwd;
// Eventually these values would be retrieved from the user's preferences
// via the settings API. For now we just use Gecko's preferences.

Просмотреть файл

@ -1 +1,7 @@
# RadioInterfaceLayer.js
component {2d831c8d-6017-435b-a80c-e5d422810cea} RadioInterfaceLayer.js
# RILContentHelper.js
component {472816e1-1fd6-4405-996c-806f9ea68174} RILContentHelper.js
contract @mozilla.org/ril/content-helper;1 {472816e1-1fd6-4405-996c-806f9ea68174}
category profile-after-change RILContentHelper @mozilla.org/ril/content-helper;1

Просмотреть файл

@ -0,0 +1,120 @@
/* 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 "nsISupports.idl"
/**
* Information about networks that is exposed to network manager API consumers.
*/
[scriptable, uuid(e016d594-3072-11e1-9b7d-0010183a41af)]
interface nsINetworkInterface : nsISupports
{
const long NETWORK_STATE_UNKNOWN = -1;
const long NETWORK_STATE_CONNECTING = 0;
const long NETWORK_STATE_CONNECTED = 1;
const long NETWORK_STATE_SUSPENDED = 2;
const long NETWORK_STATE_DISCONNECTING = 3;
const long NETWORK_STATE_DISCONNECTED = 4;
/**
* Current network state, one of the NETWORK_STATE_* constants.
*
* When this changes, network interface implementations notify the
* 'network-interface-state-changed' observer notification.
*/
readonly attribute long state;
const long NETWORK_TYPE_WIFI = 0;
const long NETWORK_TYPE_MOBILE = 1;
const long NETWORK_TYPE_MOBILE_MMS = 2;
/**
* Network type. One of the NETWORK_TYPE_* constants.
*/
readonly attribute long type;
/**
* Name of the network interface. This identifier is unique.
*/
readonly attribute DOMString name;
/**
* Indicates whether DHCP should be run when the interface connects.
*/
readonly attribute boolean dhcp;
};
/**
* Manage network interfaces.
*/
[scriptable, uuid(3bc29392-2fba-11e1-80fd-0010183a41af)]
interface nsINetworkManager : nsISupports
{
/**
* Register the given network interface with the network manager.
*
* Consumers will be notified with the 'network-interface-registered'
* observer notification.
*
* Throws if there's already an interface registered that has the same
* name.
*
* @param network
* Network interface to register.
*/
void registerNetworkInterface(in nsINetworkInterface network);
/**
* Unregister the given network interface from the network manager.
*
* Consumers will be notified with the 'network-interface-unregistered'
* observer notification.
*
* Throws an exception if the specified network interface object isn't
* registered.
*
* @param network
* Network interface to unregister.
*/
void unregisterNetworkInterface(in nsINetworkInterface network);
/**
* Object containing all known network connections, keyed by their
* interface name.
*/
readonly attribute jsval networkInterfaces;
/**
* The preferred network type. One of the
* nsINetworkInterface::NETWORK_TYPE_* constants.
*
* This attribute is used for setting default route to favor
* interfaces with given type. This can be overriden by calling
* overrideDefaultRoute().
*/
attribute long preferredNetworkType;
/**
* The network interface handling all data traffic.
*
* When this changes, the 'network-active-changed' observer
* notification is dispatched.
*/
readonly attribute nsINetworkInterface active;
/**
* Override the default behaviour for preferredNetworkType and route
* all network traffic through the the specified interface.
*
* Consumers can observe changes to the active network by subscribing to
* the 'network-active-changed' observer notification.
*
* @param network
* Network to route all network traffic to. If this is null,
* a previous override is canceled.
*/
long overrideActive(in nsINetworkInterface network);
};

Просмотреть файл

@ -38,6 +38,11 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIMobileConnectionProvider.idl"
interface nsIDOMMozMobileConnectionInfo;
interface nsIDOMDOMRequest;
interface nsIDOMWindow;
[scriptable, uuid(03eafd60-d138-4f09-81b4-90cd4996b3c7)]
interface nsIRILTelephonyCallback : nsISupports
@ -116,6 +121,15 @@ interface nsIRILDataCallback : nsISupports
in unsigned long length);
};
/**
* Helper that runs in the content process and exposes information
* to the DOM.
*/
[scriptable, uuid(cc9832fd-d3ce-4cab-9abe-48c6046bcebe)]
interface nsIRILContentHelper : nsIMobileConnectionProvider
{
};
[scriptable, uuid(d2025763-fc32-436e-b207-0228ea1ccd12)]
interface nsIRadioInterfaceLayer : nsISupports
{

Просмотреть файл

@ -35,7 +35,13 @@
*
* ***** END LICENSE BLOCK ***** */
// This must always match the CID given in RadioInterfaceLayer.manifest!
// These must always match the values given in RadioInterfaceLayer.manifest!
#define NS_RADIOINTERFACELAYER_CID \
{ 0x2d831c8d, 0x6017, 0x435b, \
{ 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
#define NS_RILCONTENTHELPER_CID \
{ 0x472816e1, 0x1fd6, 0x4405, \
{ 0x99, 0x6c, 0x80, 0x6f, 0x9e, 0xa6, 0x81, 0x74 } }
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"

Просмотреть файл

@ -1352,8 +1352,8 @@ let RIL = {
}
if (stateChanged) {
this.sendDOMMessage({type: "voiceregistrationstatechange",
voiceRegistrationState: rs});
rs.type = "voiceregistrationstatechange";
this.sendDOMMessage(rs);
}
},
@ -1374,8 +1374,8 @@ let RIL = {
}
if (stateChanged) {
this.sendDOMMessage({type: "dataregistrationstatechange",
dataRegistrationState: rs});
rs.type = "dataregistrationstatechange";
this.sendDOMMessage(rs);
}
},
@ -1430,16 +1430,13 @@ let RIL = {
_handleChangedCallState: function _handleChangedCallState(changedCall) {
let message = {type: "callStateChange",
call: {callIndex: changedCall.callIndex,
state: changedCall.state,
number: changedCall.number,
name: changedCall.name}};
call: changedCall};
this.sendDOMMessage(message);
},
_handleDisconnectedCall: function _handleDisconnectedCall(disconnectedCall) {
let message = {type: "callDisconnected",
call: {callIndex: disconnectedCall.callIndex}};
call: disconnectedCall};
this.sendDOMMessage(message);
},
@ -1924,16 +1921,27 @@ RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options)
// GSM
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
obj.gsmSignalStrength = Buf.readUint32();
// The SGS2 seems to compute the number of bars for us and expose those
// instead of the actual signal strength.
obj.bars = obj.gsmSignalStrength >> 8; //TODO remove this, see bug 729173
obj.gsmSignalStrength = obj.gsmSignalStrength & 0xff;
let gsmSignalStrength = Buf.readUint32();
obj.gsmSignalStrength = gsmSignalStrength & 0xff;
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
obj.gsmBitErrorRate = Buf.readUint32();
obj.gsmDBM = null;
obj.gsmRelative = null;
if (obj.gsmSignalStrength >= 0 && obj.gsmSignalStrength <= 31) {
obj.gsmDBM = -113 + obj.gsmSignalStrength * 2;
obj.gsmRelative = Math.floor(obj.gsmSignalStrength * 100 / 31);
}
// The SGS2 seems to compute the number of bars (0-4) for us and
// expose those instead of the actual signal strength. Since the RIL
// needs to be "warmed up" first for the quirk detection to work,
// we're detecting this ad-hoc and not upfront.
if (obj.gsmSignalStrength == 99) {
obj.gsmRelative = (gsmSignalStrength >> 8) * 25;
}
// CDMA
// The CDMA RSSI value.
obj.cdmaDBM = Buf.readUint32();
// The CDMA EC/IO.
obj.cdmaECIO = Buf.readUint32();
@ -1964,8 +1972,8 @@ RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options)
}
if (DEBUG) debug("Signal strength " + JSON.stringify(obj));
this.sendDOMMessage({type: "signalstrengthchange",
signalStrength: obj});
obj.type = "signalstrengthchange";
this.sendDOMMessage(obj);
};
RIL[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length, options) {
if (options.rilRequestError) {
@ -1998,11 +2006,11 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
this.operator.alphaLong != operator[0] ||
this.operator.alphaShort != operator[1] ||
this.operator.numeric != operator[2]) {
this.operator = {alphaLong: operator[0],
this.operator = {type: "operatorchange",
alphaLong: operator[0],
alphaShort: operator[1],
numeric: operator[2]};
this.sendDOMMessage({type: "operatorchange",
operator: this.operator});
this.sendDOMMessage(this.operator);
}
};
RIL[REQUEST_RADIO_POWER] = null;

Просмотреть файл

@ -9,6 +9,7 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const DEBUG = false; // set to true to show debug messages
@ -17,6 +18,12 @@ const WIFIWORKER_CID = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e
const WIFIWORKER_WORKER = "resource://gre/modules/wifi_worker.js";
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
"@mozilla.org/network/manager;1",
"nsINetworkManager");
// A note about errors and error handling in this file:
// The libraries that we use in this file are intended for C code. For
// C code, it is natural to return -1 for errors and 0 for success.
@ -436,8 +443,7 @@ var WifiManager = (function() {
function runDhcp(ifname, callback) {
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
dhcpInfo = data.status ? null : data;
notify("dhcpconnected", { info: dhcpInfo });
callback(data.status ? null : data);
callback(dhcpInfo);
});
}
@ -594,30 +600,33 @@ var WifiManager = (function() {
}
function dhcpAfterConnect() {
// For now we do our own DHCP. In the future, this should be handed
// off to the Network Manager.
runDhcp(manager.ifname, function (data) {
if (!data) {
debug("DHCP failed to run");
notify("dhcpconnected", { info: data });
return;
}
setProperty("net.dns1", ipToString(data.dns1), function(ok) {
setProperty("net." + manager.ifname + ".dns1", ipToString(data.dns1),
function(ok) {
if (!ok) {
debug("Unable to set net.dns1");
debug("Unable to set net.<ifname>.dns1");
return;
}
setProperty("net.dns2", ipToString(data.dns2), function(ok) {
setProperty("net." + manager.ifname + ".dns2", ipToString(data.dns2),
function(ok) {
if (!ok) {
debug("Unable to set net.dns2");
debug("Unable to set net.<ifname>.dns2");
return;
}
getProperty("net.dnschange", "0", function(value) {
if (value === null) {
debug("Unable to get net.dnschange");
setProperty("net." + manager.ifname + ".gw", ipToString(data.gateway),
function(ok) {
if (!ok) {
debug("Unable to set net.<ifname>.gw");
return;
}
setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
if (!ok)
debug("Unable to set net.dnschange");
});
notify("dhcpconnected", { info: data });
});
});
});
@ -844,6 +853,17 @@ var WifiManager = (function() {
}
manager.ifname = ifname;
// Register as network interface.
WifiNetworkInterface.name = ifname;
if (!WifiNetworkInterface.registered) {
gNetworkManager.registerNetworkInterface(WifiNetworkInterface);
WifiNetworkInterface.registered = true;
}
WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
Services.obs.notifyObservers(WifiNetworkInterface,
kNetworkInterfaceStateChangedTopic,
null);
prepareForStartup(function(already_connected) {
if (already_connected) {
callback(0);
@ -1089,6 +1109,39 @@ function isWepHexKey(s) {
return !/[^a-fA-F0-9]/.test(s);
}
let WifiNetworkInterface = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
registered: false,
// nsINetworkInterface
NETWORK_STATE_UNKNOWN: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
NETWORK_STATE_CONNECTING: Ci.nsINetworkInterface.CONNECTING,
NETWORK_STATE_CONNECTED: Ci.nsINetworkInterface.CONNECTED,
NETWORK_STATE_SUSPENDED: Ci.nsINetworkInterface.SUSPENDED,
NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInterface.DISCONNECTING,
NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInterface.DISCONNECTED,
state: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
NETWORK_TYPE_WIFI: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
NETWORK_TYPE_MOBILE: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
type: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
name: null,
// For now we do our own DHCP. In the future this should be handed off
// to the Network Manager.
dhcp: false,
};
// TODO Make the difference between a DOM-based network object and our
// networks objects much clearer.
let netToDOM;
@ -1285,15 +1338,28 @@ function WifiWorker() {
}
});
WifiNetworkInterface.state =
Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
Services.obs.notifyObservers(WifiNetworkInterface,
kNetworkInterfaceStateChangedTopic,
null);
break;
}
};
WifiManager.ondhcpconnected = function() {
if (this.info)
if (this.info) {
WifiNetworkInterface.state =
Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
Services.obs.notifyObservers(WifiNetworkInterface,
kNetworkInterfaceStateChangedTopic,
null);
self._fireEvent("onconnect", { network: netToDOM(self.currentNetwork) });
else
} else {
WifiManager.disconnect(function(){});
}
};
WifiManager.onscanresultsavailable = function() {

Просмотреть файл

@ -741,18 +741,31 @@ nsEditorSpellCheck::UpdateCurrentDictionary()
}
// If we have not set dictionary, and the editable element doesn't have a
// lang attribute, we try to get a dictionary. First try, en-US. If it does
// not work, pick the first one.
// lang attribute, we try to get a dictionary. First try LANG environment variable,
// then en-US. If it does not work, pick the first one.
if (mPreferredLang.IsEmpty()) {
nsAutoString currentDictionary;
rv = GetCurrentDictionary(currentDictionary);
if (NS_FAILED(rv) || currentDictionary.IsEmpty()) {
rv = SetCurrentDictionary(NS_LITERAL_STRING("en-US"));
// Try to get current dictionary from environment variable LANG
char* env_lang = getenv("LANG");
if (env_lang != nsnull) {
nsString lang = NS_ConvertUTF8toUTF16(env_lang);
// Strip trailing charset if there is any
PRInt32 dot_pos = lang.FindChar('.');
if (dot_pos != -1) {
lang = Substring(lang, 0, dot_pos - 1);
}
rv = SetCurrentDictionary(lang);
}
if (NS_FAILED(rv)) {
nsTArray<nsString> dictList;
rv = mSpellChecker->GetDictionaryList(&dictList);
if (NS_SUCCEEDED(rv) && dictList.Length() > 0) {
SetCurrentDictionary(dictList[0]);
rv = SetCurrentDictionary(NS_LITERAL_STRING("en-US"));
if (NS_FAILED(rv)) {
nsTArray<nsString> dictList;
rv = mSpellChecker->GetDictionaryList(&dictList);
if (NS_SUCCEEDED(rv) && dictList.Length() > 0) {
SetCurrentDictionary(dictList[0]);
}
}
}
}

Просмотреть файл

@ -75,6 +75,7 @@ _TEST_FILES = \
test_bug551704.html \
test_bug552782.html \
test_bug570144.html \
test_bug578771.html \
test_bug592592.html \
test_bug597784.html \
test_bug599322.html \

Просмотреть файл

@ -0,0 +1,63 @@
<!DOCTYPE HTML>
<!-- 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/. -->
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=578771
-->
<head>
<title>Test for Bug 578771</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=578771">Mozilla Bug 578771</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 578771 **/
SimpleTest.waitForExplicitFinish();
// Avoid platform selection differences
SpecialPowers.setBoolPref("layout.word_select.eat_space_to_next_word", false);
function testElem(elem, elemTag) {
var ce = document.getElementById("ce");
ce.focus();
synthesizeMouse(elem, 5, 5, {clickCount: 2 });
ok(elem.selectionStart == 0 && elem.selectionEnd == 7,
" Double-clicking on another " + elemTag + " works correctly");
ce.focus();
synthesizeMouse(elem, 5, 5, {clickCount: 3 });
ok(elem.selectionStart == 0 && elem.selectionEnd == 14,
"Triple-clicking on another " + elemTag + " works correctly");
}
SimpleTest.waitForFocus(function() {
var input = document.getElementById("ip");
testElem(input, "input");
var textarea = document.getElementById("ta");
testElem(textarea, "textarea");
SpecialPowers.clearUserPref("layout.word_select.eat_space_to_next_word");
SimpleTest.finish();
});
</script>
</pre>
<input id="ip" type="text" value="Mozilla editor" />
<textarea id="ta">Mozilla editor</textarea>
<div id="ce" contenteditable="true">Contenteditable div that could interfere with focus</div>
</body>
</html>

Просмотреть файл

@ -117,6 +117,7 @@ public class GeckoEvent {
public int mMetaState, mFlags;
public int mKeyCode, mUnicodeChar;
public int mRepeatCount;
public int mOffset, mCount;
public String mCharacters, mCharactersExtra;
public int mRangeType, mRangeStyles;
@ -147,6 +148,7 @@ public class GeckoEvent {
mFlags = k.getFlags();
mKeyCode = k.getKeyCode();
mUnicodeChar = k.getUnicodeChar();
mRepeatCount = k.getRepeatCount();
mCharacters = k.getCharacters();
}

Просмотреть файл

@ -8,7 +8,7 @@ http://www.cairographics.org/.
VERSIONS:
cairo (12d521df8acc483b2daa844d4f05dc2fe2765ba6)
pixman (2f4f2fb4859931bf6dc5632d8c919e7296736427)
pixman (0.24.2)
==== Patches ====
@ -188,7 +188,7 @@ NOTE: we previously supported ARM assembler on MSVC, this has been removed becau
pixman-export.patch: use cairo_public for PIXMAN_EXPORT to make sure pixman symbols are not exported in libxul
bad-memset.patch: Fix third argument in memcmp call in pixman-image.c
pixman-limits.patch: include limits.h for SIZE_MAX
==== disable printing patch ====

Просмотреть файл

@ -1,28 +0,0 @@
# HG changeset patch
# Parent a968f1430c74282c673c01a2c0a4417e238f2de7
# User Thomas Prip Vestergaard <thomas@prip.nu>
Bug 710992 - Fix third argument in memcmp call in pixman-image.c
diff --git a/gfx/cairo/libpixman/src/pixman-image.c b/gfx/cairo/libpixman/src/pixman-image.c
--- a/gfx/cairo/libpixman/src/pixman-image.c
+++ b/gfx/cairo/libpixman/src/pixman-image.c
@@ -512,17 +512,17 @@ pixman_image_set_transform (pixman_image
free (common->transform);
common->transform = NULL;
result = TRUE;
goto out;
}
if (common->transform &&
- memcmp (common->transform, transform, sizeof (pixman_transform_t) == 0))
+ memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
{
return TRUE;
}
if (common->transform == NULL)
common->transform = malloc (sizeof (pixman_transform_t));
if (common->transform == NULL)

Просмотреть файл

@ -129,6 +129,7 @@ CSRCS = \
pixman-implementation.c \
pixman-linear-gradient.c \
pixman-matrix.c \
pixman-noop.c \
pixman-radial-gradient.c \
pixman-region16.c \
pixman-region32.c \

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,21 +1,10 @@
#ifdef PIXMAN_FB_ACCESSORS
#define ACCESS(sym) sym##_accessors
#define READ(img, ptr) \
(((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr))))
#define WRITE(img, ptr,val) \
(((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr))))
#define MEMCPY_WRAPPED(img, dst, src, size) \
do { \
size_t _i; \
uint8_t *_dst = (uint8_t*)(dst), *_src = (uint8_t*)(src); \
for(_i = 0; _i < size; _i++) { \
WRITE((img), _dst +_i, READ((img), _src + _i)); \
} \
} while (0)
#define MEMSET_WRAPPED(img, dst, val, size) \
do { \
size_t _i; \
@ -27,12 +16,8 @@
#else
#define ACCESS(sym) sym
#define READ(img, ptr) (*(ptr))
#define WRITE(img, ptr, val) (*(ptr) = (val))
#define MEMCPY_WRAPPED(img, dst, src, size) \
memcpy(dst, src, size)
#define MEMSET_WRAPPED(img, dst, val, size) \
memset(dst, val, size)

Просмотреть файл

@ -26,7 +26,7 @@
#ifndef PIXMAN_ARM_COMMON_H
#define PIXMAN_ARM_COMMON_H
#include "pixman-fast-path.h"
#include "pixman-inlines.h"
/* Define some macros which can expand into proxy functions between
* ARM assembly optimized functions and the rest of pixman fast path API.
@ -63,26 +63,16 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
\
static void \
cputype##_composite_##name (pixman_implementation_t *imp, \
pixman_op_t op, \
pixman_image_t * src_image, \
pixman_image_t * mask_image, \
pixman_image_t * dst_image, \
int32_t src_x, \
int32_t src_y, \
int32_t mask_x, \
int32_t mask_y, \
int32_t dest_x, \
int32_t dest_y, \
int32_t width, \
int32_t height) \
pixman_composite_info_t *info) \
{ \
dst_type *dst_line; \
PIXMAN_COMPOSITE_ARGS (info); \
dst_type *dst_line; \
src_type *src_line; \
int32_t dst_stride, src_stride; \
\
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
src_stride, src_line, src_cnt); \
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
\
pixman_composite_##name##_asm_##cputype (width, height, \
@ -101,30 +91,20 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
\
static void \
cputype##_composite_##name (pixman_implementation_t *imp, \
pixman_op_t op, \
pixman_image_t * src_image, \
pixman_image_t * mask_image, \
pixman_image_t * dst_image, \
int32_t src_x, \
int32_t src_y, \
int32_t mask_x, \
int32_t mask_y, \
int32_t dest_x, \
int32_t dest_y, \
int32_t width, \
int32_t height) \
pixman_composite_info_t *info) \
{ \
PIXMAN_COMPOSITE_ARGS (info); \
dst_type *dst_line; \
int32_t dst_stride; \
uint32_t src; \
\
src = _pixman_image_get_solid ( \
imp, src_image, dst_image->bits.format); \
imp, src_image, dest_image->bits.format); \
\
if ((flags & SKIP_ZERO_SRC) && src == 0) \
return; \
\
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
\
pixman_composite_##name##_asm_##cputype (width, height, \
@ -147,31 +127,21 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
\
static void \
cputype##_composite_##name (pixman_implementation_t *imp, \
pixman_op_t op, \
pixman_image_t * src_image, \
pixman_image_t * mask_image, \
pixman_image_t * dst_image, \
int32_t src_x, \
int32_t src_y, \
int32_t mask_x, \
int32_t mask_y, \
int32_t dest_x, \
int32_t dest_y, \
int32_t width, \
int32_t height) \
pixman_composite_info_t *info) \
{ \
dst_type *dst_line; \
PIXMAN_COMPOSITE_ARGS (info); \
dst_type *dst_line; \
mask_type *mask_line; \
int32_t dst_stride, mask_stride; \
uint32_t src; \
\
src = _pixman_image_get_solid ( \
imp, src_image, dst_image->bits.format); \
imp, src_image, dest_image->bits.format); \
\
if ((flags & SKIP_ZERO_SRC) && src == 0) \
return; \
\
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
mask_stride, mask_line, mask_cnt); \
@ -196,31 +166,21 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
\
static void \
cputype##_composite_##name (pixman_implementation_t *imp, \
pixman_op_t op, \
pixman_image_t * src_image, \
pixman_image_t * mask_image, \
pixman_image_t * dst_image, \
int32_t src_x, \
int32_t src_y, \
int32_t mask_x, \
int32_t mask_y, \
int32_t dest_x, \
int32_t dest_y, \
int32_t width, \
int32_t height) \
pixman_composite_info_t *info) \
{ \
dst_type *dst_line; \
PIXMAN_COMPOSITE_ARGS (info); \
dst_type *dst_line; \
src_type *src_line; \
int32_t dst_stride, src_stride; \
uint32_t mask; \
\
mask = _pixman_image_get_solid ( \
imp, mask_image, dst_image->bits.format); \
imp, mask_image, dest_image->bits.format); \
\
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
return; \
\
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
src_stride, src_line, src_cnt); \
@ -247,25 +207,15 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
\
static void \
cputype##_composite_##name (pixman_implementation_t *imp, \
pixman_op_t op, \
pixman_image_t * src_image, \
pixman_image_t * mask_image, \
pixman_image_t * dst_image, \
int32_t src_x, \
int32_t src_y, \
int32_t mask_x, \
int32_t mask_y, \
int32_t dest_x, \
int32_t dest_y, \
int32_t width, \
int32_t height) \
pixman_composite_info_t *info) \
{ \
dst_type *dst_line; \
PIXMAN_COMPOSITE_ARGS (info); \
dst_type *dst_line; \
src_type *src_line; \
mask_type *mask_line; \
int32_t dst_stride, src_stride, mask_stride; \
\
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
dst_stride, dst_line, dst_cnt); \
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
src_stride, src_line, src_cnt); \
@ -398,13 +348,17 @@ scaled_bilinear_scanline_##cputype##_##name##_##op ( \
\
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint32_t, dst_type, COVER, FALSE, FALSE) \
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint32_t, dst_type, NONE, FALSE, FALSE) \
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint32_t, dst_type, PAD, FALSE, FALSE)
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint32_t, dst_type, NORMAL, \
FLAG_NONE)
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, cputype, name, op, \
@ -443,12 +397,20 @@ scaled_bilinear_scanline_##cputype##_##name##_##op ( \
\
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint8_t, dst_type, COVER, TRUE, FALSE) \
src_type, uint8_t, dst_type, COVER, \
FLAG_HAVE_NON_SOLID_MASK) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
src_type, uint8_t, dst_type, NONE, \
FLAG_HAVE_NON_SOLID_MASK) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint8_t, dst_type, PAD, TRUE, FALSE)
src_type, uint8_t, dst_type, PAD, \
FLAG_HAVE_NON_SOLID_MASK) \
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
scaled_bilinear_scanline_##cputype##_##name##_##op, \
src_type, uint8_t, dst_type, NORMAL, \
FLAG_HAVE_NON_SOLID_MASK)
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -706,13 +706,55 @@ generate_composite_function_single_scanline \
/******************************************************************************/
/* TODO: expand macros and do better instructions scheduling */
.macro pixman_composite_over_n_8888_process_pixblock_head
/* deinterleaved source pixels in {d0, d1, d2, d3} */
/* inverted alpha in {d24} */
/* destination pixels in {d4, d5, d6, d7} */
vmull.u8 q8, d24, d4
vmull.u8 q9, d24, d5
vmull.u8 q10, d24, d6
vmull.u8 q11, d24, d7
.endm
.macro pixman_composite_over_n_8888_process_pixblock_tail
vrshr.u16 q14, q8, #8
vrshr.u16 q15, q9, #8
vrshr.u16 q2, q10, #8
vrshr.u16 q3, q11, #8
vraddhn.u16 d28, q14, q8
vraddhn.u16 d29, q15, q9
vraddhn.u16 d30, q2, q10
vraddhn.u16 d31, q3, q11
vqadd.u8 q14, q0, q14
vqadd.u8 q15, q1, q15
.endm
.macro pixman_composite_over_n_8888_process_pixblock_tail_head
pixman_composite_over_8888_8888_process_pixblock_tail
vrshr.u16 q14, q8, #8
vrshr.u16 q15, q9, #8
vrshr.u16 q2, q10, #8
vrshr.u16 q3, q11, #8
vraddhn.u16 d28, q14, q8
vraddhn.u16 d29, q15, q9
vraddhn.u16 d30, q2, q10
vraddhn.u16 d31, q3, q11
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
pixman_composite_over_8888_8888_process_pixblock_head
cache_preload 8, 8
vqadd.u8 q14, q0, q14
PF add PF_X, PF_X, #8
PF tst PF_CTL, #0x0F
PF addne PF_X, PF_X, #8
PF subne PF_CTL, PF_CTL, #1
vqadd.u8 q15, q1, q15
PF cmp PF_X, ORIG_W
vmull.u8 q8, d24, d4
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
vmull.u8 q9, d24, d5
PF subge PF_X, PF_X, ORIG_W
vmull.u8 q10, d24, d6
PF subges PF_CTL, PF_CTL, #0x10
vmull.u8 q11, d24, d7
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
.endm
.macro pixman_composite_over_n_8888_init
@ -722,6 +764,7 @@ generate_composite_function_single_scanline \
vdup.8 d1, d3[1]
vdup.8 d2, d3[2]
vdup.8 d3, d3[3]
vmvn.8 d24, d3 /* get inverted alpha */
.endm
generate_composite_function \
@ -1176,6 +1219,145 @@ generate_composite_function \
/******************************************************************************/
.macro pixman_composite_src_n_8_8888_process_pixblock_head
/* expecting solid source in {d0, d1, d2, d3} */
/* mask is in d24 (d25, d26, d27 are unused) */
/* in */
vmull.u8 q8, d24, d0
vmull.u8 q9, d24, d1
vmull.u8 q10, d24, d2
vmull.u8 q11, d24, d3
vrsra.u16 q8, q8, #8
vrsra.u16 q9, q9, #8
vrsra.u16 q10, q10, #8
vrsra.u16 q11, q11, #8
.endm
.macro pixman_composite_src_n_8_8888_process_pixblock_tail
vrshrn.u16 d28, q8, #8
vrshrn.u16 d29, q9, #8
vrshrn.u16 d30, q10, #8
vrshrn.u16 d31, q11, #8
.endm
.macro pixman_composite_src_n_8_8888_process_pixblock_tail_head
fetch_mask_pixblock
PF add PF_X, PF_X, #8
vrshrn.u16 d28, q8, #8
PF tst PF_CTL, #0x0F
vrshrn.u16 d29, q9, #8
PF addne PF_X, PF_X, #8
vrshrn.u16 d30, q10, #8
PF subne PF_CTL, PF_CTL, #1
vrshrn.u16 d31, q11, #8
PF cmp PF_X, ORIG_W
vmull.u8 q8, d24, d0
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
vmull.u8 q9, d24, d1
PF subge PF_X, PF_X, ORIG_W
vmull.u8 q10, d24, d2
PF subges PF_CTL, PF_CTL, #0x10
vmull.u8 q11, d24, d3
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
vrsra.u16 q8, q8, #8
vrsra.u16 q9, q9, #8
vrsra.u16 q10, q10, #8
vrsra.u16 q11, q11, #8
.endm
.macro pixman_composite_src_n_8_8888_init
add DUMMY, sp, #ARGS_STACK_OFFSET
vld1.32 {d3[0]}, [DUMMY]
vdup.8 d0, d3[0]
vdup.8 d1, d3[1]
vdup.8 d2, d3[2]
vdup.8 d3, d3[3]
.endm
.macro pixman_composite_src_n_8_8888_cleanup
.endm
generate_composite_function \
pixman_composite_src_n_8_8888_asm_neon, 0, 8, 32, \
FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
8, /* number of pixels, processed in a single block */ \
5, /* prefetch distance */ \
pixman_composite_src_n_8_8888_init, \
pixman_composite_src_n_8_8888_cleanup, \
pixman_composite_src_n_8_8888_process_pixblock_head, \
pixman_composite_src_n_8_8888_process_pixblock_tail, \
pixman_composite_src_n_8_8888_process_pixblock_tail_head, \
/******************************************************************************/
.macro pixman_composite_src_n_8_8_process_pixblock_head
vmull.u8 q0, d24, d16
vmull.u8 q1, d25, d16
vmull.u8 q2, d26, d16
vmull.u8 q3, d27, d16
vrsra.u16 q0, q0, #8
vrsra.u16 q1, q1, #8
vrsra.u16 q2, q2, #8
vrsra.u16 q3, q3, #8
.endm
.macro pixman_composite_src_n_8_8_process_pixblock_tail
vrshrn.u16 d28, q0, #8
vrshrn.u16 d29, q1, #8
vrshrn.u16 d30, q2, #8
vrshrn.u16 d31, q3, #8
.endm
.macro pixman_composite_src_n_8_8_process_pixblock_tail_head
fetch_mask_pixblock
PF add PF_X, PF_X, #8
vrshrn.u16 d28, q0, #8
PF tst PF_CTL, #0x0F
vrshrn.u16 d29, q1, #8
PF addne PF_X, PF_X, #8
vrshrn.u16 d30, q2, #8
PF subne PF_CTL, PF_CTL, #1
vrshrn.u16 d31, q3, #8
PF cmp PF_X, ORIG_W
vmull.u8 q0, d24, d16
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
vmull.u8 q1, d25, d16
PF subge PF_X, PF_X, ORIG_W
vmull.u8 q2, d26, d16
PF subges PF_CTL, PF_CTL, #0x10
vmull.u8 q3, d27, d16
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
vst1.8 {d28, d29, d30, d31}, [DST_W, :128]!
vrsra.u16 q0, q0, #8
vrsra.u16 q1, q1, #8
vrsra.u16 q2, q2, #8
vrsra.u16 q3, q3, #8
.endm
.macro pixman_composite_src_n_8_8_init
add DUMMY, sp, #ARGS_STACK_OFFSET
vld1.32 {d16[0]}, [DUMMY]
vdup.8 d16, d16[3]
.endm
.macro pixman_composite_src_n_8_8_cleanup
.endm
generate_composite_function \
pixman_composite_src_n_8_8_asm_neon, 0, 8, 8, \
FLAG_DST_WRITEONLY, \
32, /* number of pixels, processed in a single block */ \
5, /* prefetch distance */ \
pixman_composite_src_n_8_8_init, \
pixman_composite_src_n_8_8_cleanup, \
pixman_composite_src_n_8_8_process_pixblock_head, \
pixman_composite_src_n_8_8_process_pixblock_tail, \
pixman_composite_src_n_8_8_process_pixblock_tail_head
/******************************************************************************/
.macro pixman_composite_over_n_8_8888_process_pixblock_head
/* expecting deinterleaved source data in {d8, d9, d10, d11} */
/* d8 - blue, d9 - green, d10 - red, d11 - alpha */
@ -1183,49 +1365,83 @@ generate_composite_function \
/* mask is in d24 (d25, d26, d27 are unused) */
/* in */
vmull.u8 q0, d24, d8
vmull.u8 q1, d24, d9
vmull.u8 q6, d24, d10
vmull.u8 q7, d24, d11
vrshr.u16 q10, q0, #8
vrshr.u16 q11, q1, #8
vrshr.u16 q12, q6, #8
vrshr.u16 q13, q7, #8
vraddhn.u16 d0, q0, q10
vraddhn.u16 d1, q1, q11
vraddhn.u16 d2, q6, q12
vraddhn.u16 d3, q7, q13
vmvn.8 d24, d3 /* get inverted alpha */
vmull.u8 q6, d24, d8
vmull.u8 q7, d24, d9
vmull.u8 q8, d24, d10
vmull.u8 q9, d24, d11
vrshr.u16 q10, q6, #8
vrshr.u16 q11, q7, #8
vrshr.u16 q12, q8, #8
vrshr.u16 q13, q9, #8
vraddhn.u16 d0, q6, q10
vraddhn.u16 d1, q7, q11
vraddhn.u16 d2, q8, q12
vraddhn.u16 d3, q9, q13
vmvn.8 d25, d3 /* get inverted alpha */
/* source: d0 - blue, d1 - green, d2 - red, d3 - alpha */
/* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */
/* now do alpha blending */
vmull.u8 q8, d24, d4
vmull.u8 q9, d24, d5
vmull.u8 q10, d24, d6
vmull.u8 q11, d24, d7
vmull.u8 q8, d25, d4
vmull.u8 q9, d25, d5
vmull.u8 q10, d25, d6
vmull.u8 q11, d25, d7
.endm
.macro pixman_composite_over_n_8_8888_process_pixblock_tail
vrshr.u16 q14, q8, #8
vrshr.u16 q15, q9, #8
vrshr.u16 q12, q10, #8
vrshr.u16 q13, q11, #8
vrshr.u16 q6, q10, #8
vrshr.u16 q7, q11, #8
vraddhn.u16 d28, q14, q8
vraddhn.u16 d29, q15, q9
vraddhn.u16 d30, q12, q10
vraddhn.u16 d31, q13, q11
vraddhn.u16 d30, q6, q10
vraddhn.u16 d31, q7, q11
vqadd.u8 q14, q0, q14
vqadd.u8 q15, q1, q15
.endm
/* TODO: expand macros and do better instructions scheduling */
.macro pixman_composite_over_n_8_8888_process_pixblock_tail_head
pixman_composite_over_n_8_8888_process_pixblock_tail
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
vrshr.u16 q14, q8, #8
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
vrshr.u16 q15, q9, #8
fetch_mask_pixblock
cache_preload 8, 8
pixman_composite_over_n_8_8888_process_pixblock_head
vrshr.u16 q6, q10, #8
PF add PF_X, PF_X, #8
vrshr.u16 q7, q11, #8
PF tst PF_CTL, #0x0F
vraddhn.u16 d28, q14, q8
PF addne PF_X, PF_X, #8
vraddhn.u16 d29, q15, q9
PF subne PF_CTL, PF_CTL, #1
vraddhn.u16 d30, q6, q10
PF cmp PF_X, ORIG_W
vraddhn.u16 d31, q7, q11
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
vmull.u8 q6, d24, d8
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
vmull.u8 q7, d24, d9
PF subge PF_X, PF_X, ORIG_W
vmull.u8 q8, d24, d10
PF subges PF_CTL, PF_CTL, #0x10
vmull.u8 q9, d24, d11
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
vqadd.u8 q14, q0, q14
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
vqadd.u8 q15, q1, q15
vrshr.u16 q10, q6, #8
vrshr.u16 q11, q7, #8
vrshr.u16 q12, q8, #8
vrshr.u16 q13, q9, #8
vraddhn.u16 d0, q6, q10
vraddhn.u16 d1, q7, q11
vraddhn.u16 d2, q8, q12
vraddhn.u16 d3, q9, q13
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
vmvn.8 d25, d3
vmull.u8 q8, d25, d4
vmull.u8 q9, d25, d5
vmull.u8 q10, d25, d6
vmull.u8 q11, d25, d7
.endm
.macro pixman_composite_over_n_8_8888_init
@ -1515,11 +1731,11 @@ generate_composite_function \
* output: updated src in {d0, d1, d2 } [B, G, R]
* updated mask in {d24, d25, d26} [B, G, R]
*/
vmull.u8 q1, d25, d9
vmull.u8 q6, d26, d10
vqadd.u8 q8, q0, q8
vmull.u8 q0, d24, d8
vqadd.u8 d22, d2, d22
vmull.u8 q6, d26, d10
vmull.u8 q1, d25, d9
/*
* convert the result in d16, d17, d22 to r5g6b5 and store
* it into {d28, d29}
@ -1542,6 +1758,7 @@ generate_composite_function \
vrshr.u16 q11, q12, #8
vrshr.u16 q8, q9, #8
vrshr.u16 q6, q13, #8
vraddhn.u16 d24, q12, q11
vraddhn.u16 d25, q9, q8
/*
* convert 8 r5g6b5 pixel data from {d4, d5} to planar
@ -1550,11 +1767,10 @@ generate_composite_function \
*/
vshrn.u16 d17, q2, #3
vshrn.u16 d18, q2, #8
vraddhn.u16 d24, q12, q11
vraddhn.u16 d26, q13, q6
vsli.u16 q2, q2, #5
vsri.u8 d18, d18, #5
vsri.u8 d17, d17, #6
vsri.u8 d18, d18, #5
/*
* 'combine_over_ca' replacement
*
@ -2489,6 +2705,56 @@ generate_composite_function \
/******************************************************************************/
.macro pixman_composite_out_reverse_8_8888_process_pixblock_head
/* src is in d0 */
/* destination pixel data is in {d4, d5, d6, d7} */
vmvn.8 d1, d0 /* get inverted alpha */
/* now do alpha blending */
vmull.u8 q8, d1, d4
vmull.u8 q9, d1, d5
vmull.u8 q10, d1, d6
vmull.u8 q11, d1, d7
.endm
.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail
vrshr.u16 q14, q8, #8
vrshr.u16 q15, q9, #8
vrshr.u16 q12, q10, #8
vrshr.u16 q13, q11, #8
vraddhn.u16 d28, q14, q8
vraddhn.u16 d29, q15, q9
vraddhn.u16 d30, q12, q10
vraddhn.u16 d31, q13, q11
/* 32bpp result is in {d28, d29, d30, d31} */
.endm
/* TODO: expand macros and do better instructions scheduling */
.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail_head
fetch_src_pixblock
pixman_composite_out_reverse_8_8888_process_pixblock_tail
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
cache_preload 8, 8
pixman_composite_out_reverse_8_8888_process_pixblock_head
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
.endm
generate_composite_function \
pixman_composite_out_reverse_8_8888_asm_neon, 8, 0, 32, \
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
8, /* number of pixels, processed in a single block */ \
5, /* prefetch distance */ \
default_init, \
default_cleanup, \
pixman_composite_out_reverse_8_8888_process_pixblock_head, \
pixman_composite_out_reverse_8_8888_process_pixblock_tail, \
pixman_composite_out_reverse_8_8888_process_pixblock_tail_head, \
28, /* dst_w_basereg */ \
4, /* dst_r_basereg */ \
0, /* src_basereg */ \
0 /* mask_basereg */
/******************************************************************************/
generate_composite_function_nearest_scanline \
pixman_scaled_nearest_scanline_8888_8888_OVER_asm_neon, 32, 0, 32, \
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \

Просмотреть файл

@ -64,6 +64,8 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_8888,
uint32_t, 1, uint32_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_0565,
uint8_t, 1, uint16_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_8888,
uint8_t, 1, uint32_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_0565,
uint16_t, 1)
@ -88,6 +90,10 @@ PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8,
uint8_t, 1, uint8_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8888,
uint8_t, 1, uint32_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8888,
uint8_t, 1, uint32_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8,
uint8_t, 1, uint8_t, 1)
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_8888,
uint32_t, 1, uint32_t, 1)
@ -229,8 +235,8 @@ pixman_blt_neon (uint32_t *src_bits,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{
@ -243,7 +249,7 @@ pixman_blt_neon (uint32_t *src_bits,
pixman_composite_src_0565_0565_asm_neon (
width, height,
(uint16_t *)(((char *) dst_bits) +
dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
(uint16_t *)(((char *) src_bits) +
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
return TRUE;
@ -251,7 +257,7 @@ pixman_blt_neon (uint32_t *src_bits,
pixman_composite_src_8888_8888_asm_neon (
width, height,
(uint32_t *)(((char *) dst_bits) +
dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
(uint32_t *)(((char *) src_bits) +
src_y * src_stride * 4 + src_x * 4), src_stride);
return TRUE;
@ -287,6 +293,12 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, neon_composite_src_rpixbuf_8888),
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, neon_composite_src_rpixbuf_8888),
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, neon_composite_src_pixbuf_8888),
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, neon_composite_src_n_8_8888),
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, neon_composite_src_n_8_8888),
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, neon_composite_src_n_8_8888),
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, neon_composite_src_n_8_8888),
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, neon_composite_src_n_8_8),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, neon_composite_over_n_8_8),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565),
@ -345,6 +357,8 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, neon_composite_out_reverse_8_0565),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, neon_composite_out_reverse_8_0565),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888),
PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
@ -418,20 +432,20 @@ arm_neon_blt (pixman_implementation_t *imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{
if (!pixman_blt_neon (
src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
src_x, src_y, dst_x, dst_y, width, height))
src_x, src_y, dest_x, dest_y, width, height))
{
return _pixman_implementation_blt (
imp->delegate,
src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
src_x, src_y, dst_x, dst_y, width, height);
src_x, src_y, dest_x, dest_y, width, height);
}
return TRUE;

Просмотреть файл

@ -29,7 +29,7 @@
#include "pixman-private.h"
#include "pixman-arm-common.h"
#include "pixman-fast-path.h"
#include "pixman-inlines.h"
#if 0 /* This code was moved to 'pixman-arm-simd-asm.S' */

Просмотреть файл

@ -34,6 +34,7 @@
#include <string.h>
#include "pixman-private.h"
#include "pixman-combine32.h"
#include "pixman-inlines.h"
/*
* By default, just evaluate the image at 32bpp and expand. Individual image
@ -90,34 +91,6 @@ fetch_pixel_no_alpha (bits_image_t *image,
typedef uint32_t (* get_pixel_t) (bits_image_t *image,
int x, int y, pixman_bool_t check_bounds);
static force_inline void
repeat (pixman_repeat_t repeat, int size, int *coord)
{
switch (repeat)
{
case PIXMAN_REPEAT_NORMAL:
*coord = MOD (*coord, size);
break;
case PIXMAN_REPEAT_PAD:
*coord = CLIP (*coord, 0, size - 1);
break;
case PIXMAN_REPEAT_REFLECT:
*coord = MOD (*coord, size * 2);
if (*coord >= size)
*coord = size * 2 - *coord - 1;
break;
case PIXMAN_REPEAT_NONE:
break;
default:
break;
}
}
static force_inline uint32_t
bits_image_fetch_pixel_nearest (bits_image_t *image,
pixman_fixed_t x,
@ -129,8 +102,8 @@ bits_image_fetch_pixel_nearest (bits_image_t *image,
if (image->common.repeat != PIXMAN_REPEAT_NONE)
{
repeat (image->common.repeat, image->width, &x0);
repeat (image->common.repeat, image->height, &y0);
repeat (image->common.repeat, &x0, image->width);
repeat (image->common.repeat, &y0, image->height);
return get_pixel (image, x0, y0, FALSE);
}
@ -140,97 +113,6 @@ bits_image_fetch_pixel_nearest (bits_image_t *image,
}
}
#if SIZEOF_LONG > 4
static force_inline uint32_t
bilinear_interpolation (uint32_t tl, uint32_t tr,
uint32_t bl, uint32_t br,
int distx, int disty)
{
uint64_t distxy, distxiy, distixy, distixiy;
uint64_t tl64, tr64, bl64, br64;
uint64_t f, r;
distxy = distx * disty;
distxiy = distx * (256 - disty);
distixy = (256 - distx) * disty;
distixiy = (256 - distx) * (256 - disty);
/* Alpha and Blue */
tl64 = tl & 0xff0000ff;
tr64 = tr & 0xff0000ff;
bl64 = bl & 0xff0000ff;
br64 = br & 0xff0000ff;
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
r = f & 0x0000ff0000ff0000ull;
/* Red and Green */
tl64 = tl;
tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull);
tr64 = tr;
tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull);
bl64 = bl;
bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull);
br64 = br;
br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull);
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull);
return (uint32_t)(r >> 16);
}
#else
static force_inline uint32_t
bilinear_interpolation (uint32_t tl, uint32_t tr,
uint32_t bl, uint32_t br,
int distx, int disty)
{
int distxy, distxiy, distixy, distixiy;
uint32_t f, r;
distxy = distx * disty;
distxiy = (distx << 8) - distxy; /* distx * (256 - disty) */
distixy = (disty << 8) - distxy; /* disty * (256 - distx) */
distixiy =
256 * 256 - (disty << 8) -
(distx << 8) + distxy; /* (256 - distx) * (256 - disty) */
/* Blue */
r = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy;
/* Green */
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy;
r |= f & 0xff000000;
tl >>= 16;
tr >>= 16;
bl >>= 16;
br >>= 16;
r >>= 16;
/* Red */
f = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy;
r |= f & 0x00ff0000;
/* Alpha */
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy;
r |= f & 0xff000000;
return r;
}
#endif
static force_inline uint32_t
bits_image_fetch_pixel_bilinear (bits_image_t *image,
pixman_fixed_t x,
@ -257,10 +139,10 @@ bits_image_fetch_pixel_bilinear (bits_image_t *image,
if (repeat_mode != PIXMAN_REPEAT_NONE)
{
repeat (repeat_mode, width, &x1);
repeat (repeat_mode, height, &y1);
repeat (repeat_mode, width, &x2);
repeat (repeat_mode, height, &y2);
repeat (repeat_mode, &x1, width);
repeat (repeat_mode, &y1, height);
repeat (repeat_mode, &x2, width);
repeat (repeat_mode, &y2, height);
tl = get_pixel (image, x1, y1, FALSE);
bl = get_pixel (image, x1, y2, FALSE);
@ -529,8 +411,8 @@ bits_image_fetch_pixel_convolution (bits_image_t *image,
if (repeat_mode != PIXMAN_REPEAT_NONE)
{
repeat (repeat_mode, width, &rx);
repeat (repeat_mode, height, &ry);
repeat (repeat_mode, &rx, width);
repeat (repeat_mode, &ry, height);
pixel = get_pixel (image, rx, ry, FALSE);
}
@ -812,10 +694,10 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image,
mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
repeat (repeat_mode, width, &x1);
repeat (repeat_mode, height, &y1);
repeat (repeat_mode, width, &x2);
repeat (repeat_mode, height, &y2);
repeat (repeat_mode, &x1, width);
repeat (repeat_mode, &y1, height);
repeat (repeat_mode, &x2, width);
repeat (repeat_mode, &y2, height);
row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
@ -960,8 +842,8 @@ bits_image_fetch_nearest_affine (pixman_image_t * image,
if (repeat_mode != PIXMAN_REPEAT_NONE)
{
repeat (repeat_mode, width, &x0);
repeat (repeat_mode, height, &y0);
repeat (repeat_mode, &x0, width);
repeat (repeat_mode, &y0, height);
}
row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
@ -1053,17 +935,16 @@ MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT)
MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL)
static void
bits_image_fetch_solid_32 (pixman_image_t * image,
int x,
int y,
int width,
uint32_t * buffer,
const uint32_t * mask)
replicate_pixel_32 (bits_image_t * bits,
int x,
int y,
int width,
uint32_t * buffer)
{
uint32_t color;
uint32_t *end;
color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
color = bits->fetch_pixel_32 (bits, x, y);
end = buffer + width;
while (buffer < end)
@ -1071,18 +952,17 @@ bits_image_fetch_solid_32 (pixman_image_t * image,
}
static void
bits_image_fetch_solid_64 (pixman_image_t * image,
int x,
int y,
int width,
uint32_t * b,
const uint32_t * unused)
replicate_pixel_64 (bits_image_t * bits,
int x,
int y,
int width,
uint32_t * b)
{
uint64_t color;
uint64_t *buffer = (uint64_t *)b;
uint64_t *end;
color = image->bits.fetch_pixel_64 (&image->bits, 0, 0);
color = bits->fetch_pixel_64 (bits, x, y);
end = buffer + width;
while (buffer < end)
@ -1149,6 +1029,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
while (y >= image->height)
y -= image->height;
if (image->width == 1)
{
if (wide)
replicate_pixel_64 (image, 0, y, width, buffer);
else
replicate_pixel_32 (image, 0, y, width, buffer);
return;
}
while (width)
{
while (x < 0)
@ -1219,12 +1109,6 @@ typedef struct
static const fetcher_info_t fetcher_info[] =
{
{ PIXMAN_solid,
FAST_PATH_NO_ALPHA_MAP,
bits_image_fetch_solid_32,
bits_image_fetch_solid_64
},
{ PIXMAN_any,
(FAST_PATH_NO_ALPHA_MAP |
FAST_PATH_ID_TRANSFORM |
@ -1382,12 +1266,27 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
if (image->common.alpha_map)
{
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
uint32_t *alpha;
image->common.alpha_map->fetch_scanline_32 (
(pixman_image_t *)image->common.alpha_map,
x, y, width, buffer, mask);
if ((alpha = malloc (width * sizeof (uint32_t))))
{
int i;
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
image->common.alpha_map->fetch_scanline_32 (
(pixman_image_t *)image->common.alpha_map,
x, y, width, alpha, mask);
for (i = 0; i < width; ++i)
{
buffer[i] &= ~0xff000000;
buffer[i] |= (alpha[i] & 0xff000000);
}
free (alpha);
}
}
return iter->buffer;
@ -1400,17 +1299,33 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
int x = iter->x;
int y = iter->y;
int width = iter->width;
uint32_t * buffer = iter->buffer;
uint64_t * buffer = (uint64_t *)iter->buffer;
image->fetch_scanline_64 (
(pixman_image_t *)image, x, y, width, buffer, mask);
(pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
if (image->common.alpha_map)
{
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
uint64_t *alpha;
image->common.alpha_map->fetch_scanline_64 (
(pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask);
if ((alpha = malloc (width * sizeof (uint64_t))))
{
int i;
x -= image->common.alpha_origin_x;
y -= image->common.alpha_origin_y;
image->common.alpha_map->fetch_scanline_64 (
(pixman_image_t *)image->common.alpha_map,
x, y, width, (uint32_t *)alpha, mask);
for (i = 0; i < width; ++i)
{
buffer[i] &= ~0xffff000000000000ULL;
buffer[i] |= (alpha[i] & 0xffff000000000000ULL);
}
free (alpha);
}
}
return iter->buffer;
@ -1462,43 +1377,22 @@ dest_write_back_wide (pixman_iter_t *iter)
iter->y++;
}
static void
dest_write_back_direct (pixman_iter_t *iter)
{
iter->buffer += iter->image->bits.rowstride;
}
void
_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
{
if (iter->flags & ITER_NARROW)
{
if (((image->common.flags &
(FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
(FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) &&
(image->bits.format == PIXMAN_a8r8g8b8 ||
(image->bits.format == PIXMAN_x8r8g8b8 &&
(iter->flags & ITER_LOCALIZED_ALPHA))))
if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
{
iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x;
iter->get_scanline = _pixman_iter_get_scanline_noop;
iter->write_back = dest_write_back_direct;
}
else
{
if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
{
iter->get_scanline = _pixman_iter_get_scanline_noop;
}
else
{
iter->get_scanline = dest_get_scanline_narrow;
}
iter->write_back = dest_write_back_narrow;
iter->get_scanline = dest_get_scanline_narrow;
}
iter->write_back = dest_write_back_narrow;
}
else
{
@ -1511,10 +1405,10 @@ static uint32_t *
create_bits (pixman_format_code_t format,
int width,
int height,
int * rowstride_bytes)
int * rowstride_bytes)
{
int stride;
int buf_size;
size_t buf_size;
int bpp;
/* what follows is a long-winded way, avoiding any possibility of integer
@ -1523,11 +1417,11 @@ create_bits (pixman_format_code_t format,
*/
bpp = PIXMAN_FORMAT_BPP (format);
if (pixman_multiply_overflows_int (width, bpp))
if (_pixman_multiply_overflows_int (width, bpp))
return NULL;
stride = width * bpp;
if (pixman_addition_overflows_int (stride, 0x1f))
if (_pixman_addition_overflows_int (stride, 0x1f))
return NULL;
stride += 0x1f;
@ -1535,7 +1429,7 @@ create_bits (pixman_format_code_t format,
stride *= sizeof (uint32_t);
if (pixman_multiply_overflows_int (height, stride))
if (_pixman_multiply_overflows_size (height, stride))
return NULL;
buf_size = height * stride;
@ -1546,39 +1440,29 @@ create_bits (pixman_format_code_t format,
return calloc (buf_size, 1);
}
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_bits (pixman_format_code_t format,
int width,
int height,
uint32_t * bits,
int rowstride_bytes)
pixman_bool_t
_pixman_bits_image_init (pixman_image_t * image,
pixman_format_code_t format,
int width,
int height,
uint32_t * bits,
int rowstride)
{
pixman_image_t *image;
uint32_t *free_me = NULL;
/* must be a whole number of uint32_t's
*/
return_val_if_fail (
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
if (!bits && width && height)
{
int rowstride_bytes;
free_me = bits = create_bits (format, width, height, &rowstride_bytes);
if (!bits)
return NULL;
return FALSE;
rowstride = rowstride_bytes / (int) sizeof (uint32_t);
}
image = _pixman_image_allocate ();
if (!image)
{
if (free_me)
free (free_me);
return NULL;
}
_pixman_image_init (image);
image->type = BITS;
image->bits.format = format;
@ -1588,15 +1472,43 @@ pixman_image_create_bits (pixman_format_code_t format,
image->bits.free_me = free_me;
image->bits.read_func = NULL;
image->bits.write_func = NULL;
/* The rowstride is stored in number of uint32_t */
image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t);
image->bits.rowstride = rowstride;
image->bits.indexed = NULL;
image->common.property_changed = bits_image_property_changed;
_pixman_image_reset_clip_region (image);
return TRUE;
}
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_bits (pixman_format_code_t format,
int width,
int height,
uint32_t * bits,
int rowstride_bytes)
{
pixman_image_t *image;
/* must be a whole number of uint32_t's
*/
return_val_if_fail (
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
image = _pixman_image_allocate ();
if (!image)
return NULL;
if (!_pixman_bits_image_init (image, format, width, height, bits,
rowstride_bytes / (int) sizeof (uint32_t)))
{
free (image);
return NULL;
}
return image;
}

Просмотреть файл

@ -437,7 +437,7 @@ combine_saturate_u (pixman_implementation_t *imp,
* PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
* argument. Note that this implementation operates on premultiplied colors,
* while the PDF specification does not. Therefore the code uses the formula
* ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
* Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
*/
/*
@ -522,7 +522,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
\
*(dest + i) = result + \
(DIV_ONE_UNc (sa * da) << A_SHIFT) + \
(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \
(blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \
(blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \
@ -552,7 +552,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
\
result += \
(DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \
(DIV_ONE_UNc (ALPHA_c (m) * (comp4_t)da) << A_SHIFT) + \
(blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \
(blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \
@ -849,7 +849,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
*
* r * set_sat (C, s) = set_sat (x * C, r * s)
*
* The above holds for all non-zero x, because they x'es in the fraction for
* The above holds for all non-zero x, because the x'es in the fraction for
* C_mid cancel out. Specifically, it holds for x = r:
*
* r * set_sat (C, s) = set_sat (r_c, rs)
@ -885,8 +885,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
*
* a_s * a_d * B(s, d)
* = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
* = a_s * a_d * set_lum (set_sat (a_d * S, a_s * SAT (D)),
* a_s * LUM (D), a_s * a_d)
* = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
*
*/
@ -927,7 +926,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
blend_ ## name (c, dc, da, sc, sa); \
\
*(dest + i) = result + \
(DIV_ONE_UNc (sa * da) << A_SHIFT) + \
(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \
(DIV_ONE_UNc (c[0]) << R_SHIFT) + \
(DIV_ONE_UNc (c[1]) << G_SHIFT) + \
(DIV_ONE_UNc (c[2])); \
@ -1144,9 +1143,7 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
#undef CH_MIN
#undef PDF_NON_SEPARABLE_BLEND_MODE
/* Overlay
*
* All of the disjoint composing functions
/* All of the disjoint/conjoint composing functions
*
* The four entries in the first column indicate what source contributions
* come from each of the four areas of the picture -- areas covered by neither
@ -1167,6 +1164,9 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
* (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
* (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
* (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
*
* See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
* information about these operators.
*/
#define COMBINE_A_OUT 1

Просмотреть файл

@ -25,10 +25,10 @@
*/
#define MUL_UNc(a, b, t) \
((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
((t) = (a) * (comp2_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
#define DIV_UNc(a, b) \
(((comp2_t) (a) * MASK) / (b))
(((comp2_t) (a) * MASK + ((b) / 2)) / (b))
#define ADD_UNc(x, y, t) \
((t) = (x) + (y), \

Просмотреть файл

@ -18,6 +18,12 @@
# define FUNC ((const char*) ("???"))
#endif
#if defined (__GNUC__)
# define MAYBE_UNUSED __attribute__((unused))
#else
# define MAYBE_UNUSED
#endif
#ifndef INT16_MIN
# define INT16_MIN (-32767-1)
#endif
@ -42,6 +48,15 @@
# define UINT32_MAX (4294967295U)
#endif
#ifndef INT64_MIN
# define INT64_MIN (-9223372036854775807-1)
#endif
#ifndef INT64_MAX
# define INT64_MAX (9223372036854775807)
#endif
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
@ -89,10 +104,10 @@
# define PIXMAN_GET_THREAD_LOCAL(name) \
(&name)
#elif defined(TOOLCHAIN_SUPPORTS__THREAD)
#elif defined(TLS)
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
static __thread type name
static TLS type name
# define PIXMAN_GET_THREAD_LOCAL(name) \
(&name)

Просмотреть файл

@ -24,12 +24,17 @@
#endif
#include <string.h>
#include <stdlib.h>
#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
#include <windows.h>
#endif
#if defined(__APPLE__)
#include "TargetConditionals.h"
#endif
#include "pixman-private.h"
#ifdef USE_VMX
@ -187,7 +192,7 @@ pixman_have_vmx (void)
#endif /* __APPLE__ */
#endif /* USE_VMX */
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
#if defined(_MSC_VER)
@ -244,16 +249,48 @@ pixman_have_arm_neon (void)
#endif /* USE_ARM_NEON */
#elif defined (__linux__) || defined(ANDROID) /* linux ELF */
#elif (defined (__APPLE__) && defined(TARGET_OS_IPHONE)) /* iOS (iPhone/iPad/iPod touch) */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <elf.h>
/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
* contain separate executable images for each processor architecture.
* So all we have to do is detect the armv7 architecture build. The
* operating system automatically runs the armv7 binary for armv7 devices
* and the armv6 binary for armv6 devices.
*/
pixman_bool_t
pixman_have_arm_simd (void)
{
#if defined(USE_ARM_SIMD)
return TRUE;
#else
return FALSE;
#endif
}
pixman_bool_t
pixman_have_arm_neon (void)
{
#if defined(USE_ARM_NEON) && defined(__ARM_NEON__)
/* This is an armv7 cpu build */
return TRUE;
#else
/* This is an armv6 cpu build */
return FALSE;
#endif
}
pixman_bool_t
pixman_have_arm_iwmmxt (void)
{
#if defined(USE_ARM_IWMMXT)
return FALSE;
#else
return FALSE;
#endif
}
#elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
static pixman_bool_t arm_has_v7 = FALSE;
static pixman_bool_t arm_has_v6 = FALSE;
@ -262,15 +299,10 @@ static pixman_bool_t arm_has_neon = FALSE;
static pixman_bool_t arm_has_iwmmxt = FALSE;
static pixman_bool_t arm_tests_initialized = FALSE;
#ifdef ANDROID
/* on Android, we can't reliably access /proc/self/auxv,
* so instead read the text version in /proc/cpuinfo and
* parse that instead.
*/
#if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
static void
pixman_arm_detect_cpu_features (void)
pixman_arm_read_auxv_or_cpu_features ()
{
char buf[1024];
char* pos;
@ -298,10 +330,18 @@ pixman_arm_detect_cpu_features (void)
arm_tests_initialized = TRUE;
}
#else
#elif defined (__linux__) /* linux ELF */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <elf.h>
static void
pixman_arm_detect_cpu_features (void)
pixman_arm_read_auxv_or_cpu_features ()
{
int fd;
Elf32_auxv_t aux;
@ -341,14 +381,15 @@ pixman_arm_detect_cpu_features (void)
arm_tests_initialized = TRUE;
}
#endif
#endif /* Linux elf */
#if defined(USE_ARM_SIMD)
pixman_bool_t
pixman_have_arm_simd (void)
{
if (!arm_tests_initialized)
pixman_arm_detect_cpu_features ();
pixman_arm_read_auxv_or_cpu_features ();
return arm_has_v6;
}
@ -360,23 +401,84 @@ pixman_bool_t
pixman_have_arm_neon (void)
{
if (!arm_tests_initialized)
pixman_arm_detect_cpu_features ();
pixman_arm_read_auxv_or_cpu_features ();
return arm_has_neon;
}
#endif /* USE_ARM_NEON */
#else /* linux ELF */
#if defined(USE_ARM_IWMMXT)
pixman_bool_t
pixman_have_arm_iwmmxt (void)
{
if (!arm_tests_initialized)
pixman_arm_read_auxv_or_cpu_features ();
return arm_has_iwmmxt;
}
#endif /* USE_ARM_IWMMXT */
#else /* !_MSC_VER && !Linux elf && !Android */
#define pixman_have_arm_simd() FALSE
#define pixman_have_arm_neon() FALSE
#define pixman_have_arm_iwmmxt() FALSE
#endif
#endif /* USE_ARM_SIMD || USE_ARM_NEON */
#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
#if defined(USE_MMX) || defined(USE_SSE2)
#if defined(USE_MIPS_DSPR2)
#if defined (__linux__) /* linux ELF */
pixman_bool_t
pixman_have_mips_dspr2 (void)
{
const char *search_string = "MIPS 74K";
const char *file_name = "/proc/cpuinfo";
/* Simple detection of MIPS DSP ASE (revision 2) at runtime for Linux.
* It is based on /proc/cpuinfo, which reveals hardware configuration
* to user-space applications. According to MIPS (early 2010), no similar
* facility is universally available on the MIPS architectures, so it's up
* to individual OSes to provide such.
*
* Only currently available MIPS core that supports DSPr2 is 74K.
*/
char cpuinfo_line[256];
FILE *f = NULL;
if ((f = fopen (file_name, "r")) == NULL)
return FALSE;
while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
{
if (strstr (cpuinfo_line, search_string) != NULL)
{
fclose (f);
return TRUE;
}
}
fclose (f);
/* Did not find string in the proc file. */
return FALSE;
}
#else /* linux ELF */
#define pixman_have_mips_dspr2() FALSE
#endif /* linux ELF */
#endif /* USE_MIPS_DSPR2 */
#if defined(USE_X86_MMX) || defined(USE_SSE2)
/* The CPU detection code needs to be in a file not compiled with
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
* that would lead to SIGILL instructions on old CPUs that don't have
@ -567,6 +669,7 @@ detect_cpu_features (void)
return features;
}
#ifdef USE_X86_MMX
static pixman_bool_t
pixman_have_mmx (void)
{
@ -582,6 +685,7 @@ pixman_have_mmx (void)
return mmx_present;
}
#endif
#ifdef USE_SSE2
static pixman_bool_t
@ -603,7 +707,7 @@ pixman_have_sse2 (void)
#endif
#else /* __amd64__ */
#ifdef USE_MMX
#ifdef USE_X86_MMX
#define pixman_have_mmx() TRUE
#endif
#ifdef USE_SSE2
@ -612,39 +716,84 @@ pixman_have_sse2 (void)
#endif /* __amd64__ */
#endif
static pixman_bool_t
disabled (const char *name)
{
const char *env;
if ((env = getenv ("PIXMAN_DISABLE")))
{
do
{
const char *end;
int len;
if ((end = strchr (env, ' ')))
len = end - env;
else
len = strlen (env);
if (strlen (name) == len && strncmp (name, env, len) == 0)
{
printf ("pixman: Disabled %s implementation\n", name);
return TRUE;
}
env += len;
}
while (*env++);
}
return FALSE;
}
pixman_implementation_t *
_pixman_choose_implementation (void)
{
pixman_implementation_t *imp;
imp = _pixman_implementation_create_general();
imp = _pixman_implementation_create_fast_path (imp);
#ifdef USE_MMX
if (pixman_have_mmx ())
if (!disabled ("fast"))
imp = _pixman_implementation_create_fast_path (imp);
#ifdef USE_X86_MMX
if (!disabled ("mmx") && pixman_have_mmx ())
imp = _pixman_implementation_create_mmx (imp);
#endif
#ifdef USE_SSE2
if (pixman_have_sse2 ())
if (!disabled ("sse2") && pixman_have_sse2 ())
imp = _pixman_implementation_create_sse2 (imp);
#endif
#ifdef USE_ARM_SIMD
if (pixman_have_arm_simd ())
if (!disabled ("arm-simd") && pixman_have_arm_simd ())
imp = _pixman_implementation_create_arm_simd (imp);
#endif
#ifdef USE_ARM_IWMMXT
if (!disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
imp = _pixman_implementation_create_mmx (imp);
#endif
#ifdef USE_ARM_NEON
if (pixman_have_arm_neon ())
if (!disabled ("arm-neon") && pixman_have_arm_neon ())
imp = _pixman_implementation_create_arm_neon (imp);
#endif
#ifdef USE_MIPS_DSPR2
if (!disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
imp = _pixman_implementation_create_mips_dspr2 (imp);
#endif
#ifdef USE_VMX
if (pixman_have_vmx ())
if (!disabled ("vmx") && pixman_have_vmx ())
imp = _pixman_implementation_create_vmx (imp);
#endif
imp = _pixman_implementation_create_noop (imp);
return imp;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -101,19 +101,9 @@ static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
static void
general_composite_rect (pixman_implementation_t *imp,
pixman_op_t op,
pixman_image_t * src,
pixman_image_t * mask,
pixman_image_t * dest,
int32_t src_x,
int32_t src_y,
int32_t mask_x,
int32_t mask_y,
int32_t dest_x,
int32_t dest_y,
int32_t width,
int32_t height)
pixman_composite_info_t *info)
{
PIXMAN_COMPOSITE_ARGS (info);
uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
@ -124,9 +114,9 @@ general_composite_rect (pixman_implementation_t *imp,
int Bpp;
int i;
if ((src->common.flags & FAST_PATH_NARROW_FORMAT) &&
(!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
(dest->common.flags & FAST_PATH_NARROW_FORMAT))
if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
(dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
{
narrow = ITER_NARROW;
Bpp = 4;
@ -152,7 +142,7 @@ general_composite_rect (pixman_implementation_t *imp,
/* src iter */
src_flags = narrow | op_flags[op].src;
_pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
_pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
src_x, src_y, width, height,
src_buffer, src_flags);
@ -163,39 +153,26 @@ general_composite_rect (pixman_implementation_t *imp,
/* If it doesn't matter what the source is, then it doesn't matter
* what the mask is
*/
mask = NULL;
mask_image = NULL;
}
component_alpha =
mask &&
mask->common.type == BITS &&
mask->common.component_alpha &&
PIXMAN_FORMAT_RGB (mask->bits.format);
mask_image &&
mask_image->common.type == BITS &&
mask_image->common.component_alpha &&
PIXMAN_FORMAT_RGB (mask_image->bits.format);
_pixman_implementation_src_iter_init (
imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height,
imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB));
/* dest iter */
_pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
dest_x, dest_y, width, height,
dest_buffer,
narrow | op_flags[op].dst);
_pixman_implementation_dest_iter_init (
imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
dest_buffer, narrow | op_flags[op].dst);
if (narrow)
{
if (component_alpha)
compose = _pixman_implementation_combine_32_ca;
else
compose = _pixman_implementation_combine_32;
}
else
{
if (component_alpha)
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
else
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
}
compose = _pixman_implementation_lookup_combiner (
imp->toplevel, op, component_alpha, narrow);
if (!compose)
return;
@ -233,8 +210,8 @@ general_blt (pixman_implementation_t *imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{

Просмотреть файл

@ -31,7 +31,7 @@
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
unsigned int spread)
pixman_repeat_t repeat)
{
walker->num_stops = gradient->n_stops;
walker->stops = gradient->stops;
@ -42,112 +42,54 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
walker->left_rb = 0;
walker->right_ag = 0;
walker->right_rb = 0;
walker->spread = spread;
walker->repeat = repeat;
walker->need_reset = TRUE;
}
void
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
pixman_fixed_32_32_t pos)
static void
gradient_walker_reset (pixman_gradient_walker_t *walker,
pixman_fixed_48_16_t pos)
{
int32_t x, left_x, right_x;
pixman_color_t *left_c, *right_c;
pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
pixman_gradient_stop_t * stops = walker->stops;
pixman_gradient_stop_t *stops = walker->stops;
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
switch (walker->spread)
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
{
case PIXMAN_REPEAT_NORMAL:
x = (int32_t)pos & 0xFFFF;
for (n = 0; n < count; n++)
if (x < stops[n].x)
break;
if (n == 0)
{
left_x = stops[count - 1].x - 0x10000;
left_c = &stops[count - 1].color;
}
else
{
left_x = stops[n - 1].x;
left_c = &stops[n - 1].color;
}
if (n == count)
{
right_x = stops[0].x + 0x10000;
right_c = &stops[0].color;
}
else
{
right_x = stops[n].x;
right_c = &stops[n].color;
}
left_x += (pos - x);
right_x += (pos - x);
break;
case PIXMAN_REPEAT_PAD:
for (n = 0; n < count; n++)
if (pos < stops[n].x)
break;
if (n == 0)
{
left_x = INT32_MIN;
left_c = &stops[0].color;
}
else
{
left_x = stops[n - 1].x;
left_c = &stops[n - 1].color;
}
if (n == count)
{
right_x = INT32_MAX;
right_c = &stops[n - 1].color;
}
else
{
right_x = stops[n].x;
right_c = &stops[n].color;
}
break;
case PIXMAN_REPEAT_REFLECT:
x = (int32_t)pos & 0xFFFF;
x = (int32_t)pos & 0xffff;
}
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
{
x = (int32_t)pos & 0xffff;
if ((int32_t)pos & 0x10000)
x = 0x10000 - x;
for (n = 0; n < count; n++)
if (x < stops[n].x)
break;
if (n == 0)
{
left_x = -stops[0].x;
left_c = &stops[0].color;
}
else
{
left_x = stops[n - 1].x;
left_c = &stops[n - 1].color;
}
if (n == count)
{
right_x = 0x20000 - stops[n - 1].x;
right_c = &stops[n - 1].color;
}
else
{
right_x = stops[n].x;
right_c = &stops[n].color;
}
}
else
{
x = pos;
}
for (n = 0; n < count; n++)
{
if (x < stops[n].x)
break;
}
left_x = stops[n - 1].x;
left_c = &stops[n - 1].color;
right_x = stops[n].x;
right_c = &stops[n].color;
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
{
left_x += (pos - x);
right_x += (pos - x);
}
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
{
if ((int32_t)pos & 0x10000)
{
pixman_color_t *tmp_c;
@ -165,32 +107,13 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
}
left_x += (pos - x);
right_x += (pos - x);
break;
default: /* REPEAT_NONE */
for (n = 0; n < count; n++)
if (pos < stops[n].x)
break;
}
else if (walker->repeat == PIXMAN_REPEAT_NONE)
{
if (n == 0)
{
left_x = INT32_MIN;
right_x = stops[0].x;
left_c = right_c = (pixman_color_t*) &transparent_black;
}
right_c = left_c;
else if (n == count)
{
left_x = stops[n - 1].x;
right_x = INT32_MAX;
left_c = right_c = (pixman_color_t*) &transparent_black;
}
else
{
left_x = stops[n - 1].x;
right_x = stops[n].x;
left_c = &stops[n - 1].color;
right_c = &stops[n].color;
}
left_c = right_c;
}
walker->left_x = left_x;
@ -201,8 +124,8 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
if (walker->left_x == walker->right_x ||
( walker->left_ag == walker->right_ag &&
walker->left_rb == walker->right_rb ) )
(walker->left_ag == walker->right_ag &&
walker->left_rb == walker->right_rb))
{
walker->stepper = 0;
}
@ -215,20 +138,15 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->need_reset = FALSE;
}
#define PIXMAN_GRADIENT_WALKER_NEED_RESET(w, x) \
( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
pixman_fixed_32_32_t x)
pixman_fixed_48_16_t x)
{
int dist, idist;
uint32_t t1, t2, a, color;
if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
_pixman_gradient_walker_reset (walker, x);
if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
gradient_walker_reset (walker, x);
dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
idist = 256 - dist;

Просмотреть файл

@ -31,6 +31,50 @@
#include "pixman-private.h"
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
static void
gradient_property_changed (pixman_image_t *image)
{
gradient_t *gradient = &image->gradient;
int n = gradient->n_stops;
pixman_gradient_stop_t *stops = gradient->stops;
pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
pixman_gradient_stop_t *end = &(gradient->stops[n]);
switch (gradient->common.repeat)
{
default:
case PIXMAN_REPEAT_NONE:
begin->x = INT32_MIN;
begin->color = transparent_black;
end->x = INT32_MAX;
end->color = transparent_black;
break;
case PIXMAN_REPEAT_NORMAL:
begin->x = stops[n - 1].x - pixman_fixed_1;
begin->color = stops[n - 1].color;
end->x = stops[0].x + pixman_fixed_1;
end->color = stops[0].color;
break;
case PIXMAN_REPEAT_REFLECT:
begin->x = - stops[0].x;
begin->color = stops[0].color;
end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
end->color = stops[n - 1].color;
break;
case PIXMAN_REPEAT_PAD:
begin->x = INT32_MIN;
begin->color = stops[0].color;
end->x = INT32_MAX;
end->color = stops[n - 1].color;
break;
}
}
pixman_bool_t
_pixman_init_gradient (gradient_t * gradient,
const pixman_gradient_stop_t *stops,
@ -38,45 +82,109 @@ _pixman_init_gradient (gradient_t * gradient,
{
return_val_if_fail (n_stops > 0, FALSE);
gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
/* We allocate two extra stops, one before the beginning of the stop list,
* and one after the end. These stops are initialized to whatever color
* would be used for positions outside the range of the stop list.
*
* This saves a bit of computation in the gradient walker.
*
* The pointer we store in the gradient_t struct still points to the
* first user-supplied struct, so when freeing, we will have to
* subtract one.
*/
gradient->stops =
pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
if (!gradient->stops)
return FALSE;
gradient->stops += 1;
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
gradient->n_stops = n_stops;
gradient->common.property_changed = gradient_property_changed;
return TRUE;
}
void
_pixman_image_init (pixman_image_t *image)
{
image_common_t *common = &image->common;
pixman_region32_init (&common->clip_region);
common->alpha_count = 0;
common->have_clip_region = FALSE;
common->clip_sources = FALSE;
common->transform = NULL;
common->repeat = PIXMAN_REPEAT_NONE;
common->filter = PIXMAN_FILTER_NEAREST;
common->filter_params = NULL;
common->n_filter_params = 0;
common->alpha_map = NULL;
common->component_alpha = FALSE;
common->ref_count = 1;
common->property_changed = NULL;
common->client_clip = FALSE;
common->destroy_func = NULL;
common->destroy_data = NULL;
common->dirty = TRUE;
}
pixman_bool_t
_pixman_image_fini (pixman_image_t *image)
{
image_common_t *common = (image_common_t *)image;
common->ref_count--;
if (common->ref_count == 0)
{
if (image->common.destroy_func)
image->common.destroy_func (image, image->common.destroy_data);
pixman_region32_fini (&common->clip_region);
free (common->transform);
free (common->filter_params);
if (common->alpha_map)
pixman_image_unref ((pixman_image_t *)common->alpha_map);
if (image->type == LINEAR ||
image->type == RADIAL ||
image->type == CONICAL)
{
if (image->gradient.stops)
{
/* See _pixman_init_gradient() for an explanation of the - 1 */
free (image->gradient.stops - 1);
}
/* This will trigger if someone adds a property_changed
* method to the linear/radial/conical gradient overwriting
* the general one.
*/
assert (
image->common.property_changed == gradient_property_changed);
}
if (image->type == BITS && image->bits.free_me)
free (image->bits.free_me);
return TRUE;
}
return FALSE;
}
pixman_image_t *
_pixman_image_allocate (void)
{
pixman_image_t *image = malloc (sizeof (pixman_image_t));
if (image)
{
image_common_t *common = &image->common;
pixman_region32_init (&common->clip_region);
common->alpha_count = 0;
common->have_clip_region = FALSE;
common->clip_sources = FALSE;
common->transform = NULL;
common->repeat = PIXMAN_REPEAT_NONE;
common->filter = PIXMAN_FILTER_NEAREST;
common->filter_params = NULL;
common->n_filter_params = 0;
common->alpha_map = NULL;
common->component_alpha = FALSE;
common->ref_count = 1;
common->property_changed = NULL;
common->client_clip = FALSE;
common->destroy_func = NULL;
common->destroy_data = NULL;
common->dirty = TRUE;
}
_pixman_image_init (image);
return image;
}
@ -100,39 +208,9 @@ pixman_image_ref (pixman_image_t *image)
PIXMAN_EXPORT pixman_bool_t
pixman_image_unref (pixman_image_t *image)
{
image_common_t *common = (image_common_t *)image;
common->ref_count--;
if (common->ref_count == 0)
if (_pixman_image_fini (image))
{
if (image->common.destroy_func)
image->common.destroy_func (image, image->common.destroy_data);
pixman_region32_fini (&common->clip_region);
if (common->transform)
free (common->transform);
if (common->filter_params)
free (common->filter_params);
if (common->alpha_map)
pixman_image_unref ((pixman_image_t *)common->alpha_map);
if (image->type == LINEAR ||
image->type == RADIAL ||
image->type == CONICAL)
{
if (image->gradient.stops)
free (image->gradient.stops);
}
if (image->type == BITS && image->bits.free_me)
free (image->bits.free_me);
free (image);
return TRUE;
}
@ -221,13 +299,12 @@ compute_image_info (pixman_image_t *image)
image->common.transform->matrix[1][1] == 0)
{
pixman_fixed_t m01 = image->common.transform->matrix[0][1];
if (m01 == -image->common.transform->matrix[1][0])
{
if (m01 == -pixman_fixed_1)
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
else if (m01 == pixman_fixed_1)
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
}
pixman_fixed_t m10 = image->common.transform->matrix[1][0];
if (m01 == -1 && m10 == 1)
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
else if (m01 == 1 && m10 == -1)
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
}
}
@ -250,6 +327,47 @@ compute_image_info (pixman_image_t *image)
case PIXMAN_FILTER_GOOD:
case PIXMAN_FILTER_BEST:
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
/* Here we have a chance to optimize BILINEAR filter to NEAREST if
* they are equivalent for the currently used transformation matrix.
*/
if (flags & FAST_PATH_ID_TRANSFORM)
{
flags |= FAST_PATH_NEAREST_FILTER;
}
else if (
/* affine and integer translation components in matrix ... */
((flags & FAST_PATH_AFFINE_TRANSFORM) &&
!pixman_fixed_frac (image->common.transform->matrix[0][2] |
image->common.transform->matrix[1][2])) &&
(
/* ... combined with a simple rotation */
(flags & (FAST_PATH_ROTATE_90_TRANSFORM |
FAST_PATH_ROTATE_180_TRANSFORM |
FAST_PATH_ROTATE_270_TRANSFORM)) ||
/* ... or combined with a simple non-rotated translation */
(image->common.transform->matrix[0][0] == pixman_fixed_1 &&
image->common.transform->matrix[1][1] == pixman_fixed_1 &&
image->common.transform->matrix[0][1] == 0 &&
image->common.transform->matrix[1][0] == 0)
)
)
{
/* FIXME: there are some affine-test failures, showing that
* handling of BILINEAR and NEAREST filter is not quite
* equivalent when getting close to 32K for the translation
* components of the matrix. That's likely some bug, but for
* now just skip BILINEAR->NEAREST optimization in this case.
*/
pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
if (image->common.transform->matrix[0][2] <= magic_limit &&
image->common.transform->matrix[1][2] <= magic_limit &&
image->common.transform->matrix[0][2] >= -magic_limit &&
image->common.transform->matrix[1][2] >= -magic_limit)
{
flags |= FAST_PATH_NEAREST_FILTER;
}
}
break;
case PIXMAN_FILTER_CONVOLUTION:
@ -320,12 +438,7 @@ compute_image_info (pixman_image_t *image)
else
{
code = image->bits.format;
if (!image->common.transform &&
image->common.repeat == PIXMAN_REPEAT_NORMAL)
{
flags |= FAST_PATH_SIMPLE_REPEAT | FAST_PATH_SAMPLES_COVER_CLIP;
}
flags |= FAST_PATH_BITS_IMAGE;
}
if (!PIXMAN_FORMAT_A (image->bits.format) &&

Просмотреть файл

@ -27,54 +27,6 @@
#include <stdlib.h>
#include "pixman-private.h"
static void
delegate_combine_32 (pixman_implementation_t * imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width)
{
_pixman_implementation_combine_32 (imp->delegate,
op, dest, src, mask, width);
}
static void
delegate_combine_64 (pixman_implementation_t * imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width)
{
_pixman_implementation_combine_64 (imp->delegate,
op, dest, src, mask, width);
}
static void
delegate_combine_32_ca (pixman_implementation_t * imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width)
{
_pixman_implementation_combine_32_ca (imp->delegate,
op, dest, src, mask, width);
}
static void
delegate_combine_64_ca (pixman_implementation_t * imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width)
{
_pixman_implementation_combine_64_ca (imp->delegate,
op, dest, src, mask, width);
}
static pixman_bool_t
delegate_blt (pixman_implementation_t * imp,
uint32_t * src_bits,
@ -85,14 +37,14 @@ delegate_blt (pixman_implementation_t * imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{
return _pixman_implementation_blt (
imp->delegate, src_bits, dst_bits, src_stride, dst_stride,
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
width, height);
}
@ -150,61 +102,44 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
imp->src_iter_init = delegate_src_iter_init;
imp->dest_iter_init = delegate_dest_iter_init;
imp->fast_paths = fast_paths;
for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
{
imp->combine_32[i] = delegate_combine_32;
imp->combine_64[i] = delegate_combine_64;
imp->combine_32_ca[i] = delegate_combine_32_ca;
imp->combine_64_ca[i] = delegate_combine_64_ca;
imp->combine_32[i] = NULL;
imp->combine_64[i] = NULL;
imp->combine_32_ca[i] = NULL;
imp->combine_64_ca[i] = NULL;
}
imp->fast_paths = fast_paths;
return imp;
}
void
_pixman_implementation_combine_32 (pixman_implementation_t * imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width)
pixman_combine_32_func_t
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
pixman_op_t op,
pixman_bool_t component_alpha,
pixman_bool_t narrow)
{
(*imp->combine_32[op]) (imp, op, dest, src, mask, width);
}
pixman_combine_32_func_t f;
void
_pixman_implementation_combine_64 (pixman_implementation_t * imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width)
{
(*imp->combine_64[op]) (imp, op, dest, src, mask, width);
}
do
{
pixman_combine_32_func_t (*combiners[]) =
{
(pixman_combine_32_func_t *)imp->combine_64,
(pixman_combine_32_func_t *)imp->combine_64_ca,
imp->combine_32,
imp->combine_32_ca,
};
void
_pixman_implementation_combine_32_ca (pixman_implementation_t * imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width)
{
(*imp->combine_32_ca[op]) (imp, op, dest, src, mask, width);
}
f = combiners[component_alpha | (narrow << 1)][op];
void
_pixman_implementation_combine_64_ca (pixman_implementation_t * imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width)
{
(*imp->combine_64_ca[op]) (imp, op, dest, src, mask, width);
imp = imp->delegate;
}
while (!f);
return f;
}
pixman_bool_t
@ -217,13 +152,13 @@ _pixman_implementation_blt (pixman_implementation_t * imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{
return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
width, height);
}
@ -241,12 +176,6 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor);
}
static uint32_t *
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
{
return NULL;
}
void
_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
@ -266,19 +195,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp,
iter->height = height;
iter->flags = flags;
if (!image)
{
iter->get_scanline = get_scanline_null;
}
else if ((flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
{
iter->get_scanline = _pixman_iter_get_scanline_noop;
}
else
{
(*imp->src_iter_init) (imp, iter);
}
(*imp->src_iter_init) (imp, iter);
}
void

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,164 @@
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
/*
* Copyright © 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "pixman-private.h"
#include "pixman-combine32.h"
#include "pixman-inlines.h"
static void
noop_composite (pixman_implementation_t *imp,
pixman_composite_info_t *info)
{
return;
}
static void
dest_write_back_direct (pixman_iter_t *iter)
{
iter->buffer += iter->image->bits.rowstride;
}
static uint32_t *
noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
{
uint32_t *result = iter->buffer;
iter->buffer += iter->image->bits.rowstride;
return result;
}
static uint32_t *
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
{
return NULL;
}
static void
noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
{
pixman_image_t *image = iter->image;
#define FLAGS \
(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM)
if (!image)
{
iter->get_scanline = get_scanline_null;
}
else if ((iter->flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
{
iter->get_scanline = _pixman_iter_get_scanline_noop;
}
else if (image->common.extended_format_code == PIXMAN_solid &&
((image->common.flags & (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)) ==
(FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)))
{
bits_image_t *bits = &image->bits;
if (iter->flags & ITER_NARROW)
{
uint32_t color = bits->fetch_pixel_32 (bits, 0, 0);
uint32_t *buffer = iter->buffer;
uint32_t *end = buffer + iter->width;
while (buffer < end)
*(buffer++) = color;
}
else
{
uint64_t color = bits->fetch_pixel_64 (bits, 0, 0);
uint64_t *buffer = (uint64_t *)iter->buffer;
uint64_t *end = buffer + iter->width;
while (buffer < end)
*(buffer++) = color;
}
iter->get_scanline = _pixman_iter_get_scanline_noop;
}
else if (image->common.extended_format_code == PIXMAN_a8r8g8b8 &&
(iter->flags & ITER_NARROW) &&
(image->common.flags & FLAGS) == FLAGS &&
iter->x >= 0 && iter->y >= 0 &&
iter->x + iter->width <= image->bits.width &&
iter->y + iter->height <= image->bits.height)
{
iter->buffer =
image->bits.bits + iter->y * image->bits.rowstride + iter->x;
iter->get_scanline = noop_get_scanline;
}
else
{
(* imp->delegate->src_iter_init) (imp->delegate, iter);
}
}
static void
noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
{
pixman_image_t *image = iter->image;
uint32_t image_flags = image->common.flags;
uint32_t iter_flags = iter->flags;
if ((image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS &&
(iter_flags & ITER_NARROW) == ITER_NARROW &&
((image->common.extended_format_code == PIXMAN_a8r8g8b8) ||
(image->common.extended_format_code == PIXMAN_x8r8g8b8 &&
(iter_flags & (ITER_LOCALIZED_ALPHA)))))
{
iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x;
iter->get_scanline = _pixman_iter_get_scanline_noop;
iter->write_back = dest_write_back_direct;
}
else
{
(* imp->delegate->dest_iter_init) (imp->delegate, iter);
}
}
static const pixman_fast_path_t noop_fast_paths[] =
{
{ PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite },
{ PIXMAN_OP_NONE },
};
pixman_implementation_t *
_pixman_implementation_create_noop (pixman_implementation_t *fallback)
{
pixman_implementation_t *imp =
_pixman_implementation_create (fallback, noop_fast_paths);
imp->src_iter_init = noop_src_iter_init;
imp->dest_iter_init = noop_dest_iter_init;
return imp;
}

Просмотреть файл

@ -250,6 +250,19 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
void
_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
void
_pixman_image_init (pixman_image_t *image);
pixman_bool_t
_pixman_bits_image_init (pixman_image_t * image,
pixman_format_code_t format,
int width,
int height,
uint32_t * bits,
int rowstride);
pixman_bool_t
_pixman_image_fini (pixman_image_t *image);
pixman_image_t *
_pixman_image_allocate (void);
@ -286,29 +299,29 @@ typedef struct
uint32_t left_rb;
uint32_t right_ag;
uint32_t right_rb;
int32_t left_x;
int32_t right_x;
int32_t stepper;
pixman_fixed_t left_x;
pixman_fixed_t right_x;
pixman_fixed_t stepper;
pixman_gradient_stop_t *stops;
int num_stops;
unsigned int spread;
pixman_repeat_t repeat;
int need_reset;
pixman_bool_t need_reset;
} pixman_gradient_walker_t;
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
unsigned int spread);
pixman_repeat_t repeat);
void
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
pixman_fixed_32_32_t pos);
pixman_fixed_48_16_t pos);
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
pixman_fixed_32_32_t x);
pixman_fixed_48_16_t x);
/*
* Edges
@ -346,6 +359,40 @@ pixman_rasterize_edges_accessors (pixman_image_t *image,
*/
typedef struct pixman_implementation_t pixman_implementation_t;
typedef struct
{
pixman_op_t op;
pixman_image_t * src_image;
pixman_image_t * mask_image;
pixman_image_t * dest_image;
int32_t src_x;
int32_t src_y;
int32_t mask_x;
int32_t mask_y;
int32_t dest_x;
int32_t dest_y;
int32_t width;
int32_t height;
uint32_t src_flags;
uint32_t mask_flags;
uint32_t dest_flags;
} pixman_composite_info_t;
#define PIXMAN_COMPOSITE_ARGS(info) \
MAYBE_UNUSED pixman_op_t op = info->op; \
MAYBE_UNUSED pixman_image_t * src_image = info->src_image; \
MAYBE_UNUSED pixman_image_t * mask_image = info->mask_image; \
MAYBE_UNUSED pixman_image_t * dest_image = info->dest_image; \
MAYBE_UNUSED int32_t src_x = info->src_x; \
MAYBE_UNUSED int32_t src_y = info->src_y; \
MAYBE_UNUSED int32_t mask_x = info->mask_x; \
MAYBE_UNUSED int32_t mask_y = info->mask_y; \
MAYBE_UNUSED int32_t dest_x = info->dest_x; \
MAYBE_UNUSED int32_t dest_y = info->dest_y; \
MAYBE_UNUSED int32_t width = info->width; \
MAYBE_UNUSED int32_t height = info->height
typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
pixman_op_t op,
uint32_t * dest,
@ -361,18 +408,7 @@ typedef void (*pixman_combine_64_func_t) (pixman_implementation_t *imp,
int width);
typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp,
pixman_op_t op,
pixman_image_t * src,
pixman_image_t * mask,
pixman_image_t * dest,
int32_t src_x,
int32_t src_y,
int32_t mask_x,
int32_t mask_y,
int32_t dest_x,
int32_t dest_y,
int32_t width,
int32_t height);
pixman_composite_info_t *info);
typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
uint32_t * src_bits,
uint32_t * dst_bits,
@ -382,8 +418,8 @@ typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height);
typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
@ -439,34 +475,11 @@ pixman_implementation_t *
_pixman_implementation_create (pixman_implementation_t *delegate,
const pixman_fast_path_t *fast_paths);
void
_pixman_implementation_combine_32 (pixman_implementation_t *imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width);
void
_pixman_implementation_combine_64 (pixman_implementation_t *imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width);
void
_pixman_implementation_combine_32_ca (pixman_implementation_t *imp,
pixman_op_t op,
uint32_t * dest,
const uint32_t * src,
const uint32_t * mask,
int width);
void
_pixman_implementation_combine_64_ca (pixman_implementation_t *imp,
pixman_op_t op,
uint64_t * dest,
const uint64_t * src,
const uint64_t * mask,
int width);
pixman_combine_32_func_t
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
pixman_op_t op,
pixman_bool_t component_alpha,
pixman_bool_t wide);
pixman_bool_t
_pixman_implementation_blt (pixman_implementation_t *imp,
@ -478,8 +491,8 @@ _pixman_implementation_blt (pixman_implementation_t *imp,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height);
@ -523,7 +536,10 @@ _pixman_implementation_create_general (void);
pixman_implementation_t *
_pixman_implementation_create_fast_path (pixman_implementation_t *fallback);
#ifdef USE_MMX
pixman_implementation_t *
_pixman_implementation_create_noop (pixman_implementation_t *fallback);
#if defined USE_X86_MMX || defined USE_ARM_IWMMXT
pixman_implementation_t *
_pixman_implementation_create_mmx (pixman_implementation_t *fallback);
#endif
@ -543,6 +559,11 @@ pixman_implementation_t *
_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback);
#endif
#ifdef USE_MIPS_DSPR2
pixman_implementation_t *
_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback);
#endif
#ifdef USE_VMX
pixman_implementation_t *
_pixman_implementation_create_vmx (pixman_implementation_t *fallback);
@ -587,15 +608,16 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
#define FAST_PATH_IS_OPAQUE (1 << 13)
#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14)
#define FAST_PATH_NO_NONE_REPEAT (1 << 15)
#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16)
#define FAST_PATH_X_UNIT_POSITIVE (1 << 17)
#define FAST_PATH_AFFINE_TRANSFORM (1 << 18)
#define FAST_PATH_Y_UNIT_ZERO (1 << 19)
#define FAST_PATH_BILINEAR_FILTER (1 << 20)
#define FAST_PATH_ROTATE_90_TRANSFORM (1 << 21)
#define FAST_PATH_ROTATE_180_TRANSFORM (1 << 22)
#define FAST_PATH_ROTATE_270_TRANSFORM (1 << 23)
#define FAST_PATH_SIMPLE_REPEAT (1 << 24)
#define FAST_PATH_X_UNIT_POSITIVE (1 << 16)
#define FAST_PATH_AFFINE_TRANSFORM (1 << 17)
#define FAST_PATH_Y_UNIT_ZERO (1 << 18)
#define FAST_PATH_BILINEAR_FILTER (1 << 19)
#define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20)
#define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21)
#define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22)
#define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23)
#define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24)
#define FAST_PATH_BITS_IMAGE (1 << 25)
#define FAST_PATH_PAD_REPEAT \
(FAST_PATH_NO_NONE_REPEAT | \
@ -631,7 +653,7 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
#define SOURCE_FLAGS(format) \
(FAST_PATH_STANDARD_FLAGS | \
((PIXMAN_ ## format == PIXMAN_solid) ? \
0 : (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_ID_TRANSFORM)))
0 : (FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | FAST_PATH_NEAREST_FILTER | FAST_PATH_ID_TRANSFORM)))
#define MASK_FLAGS(format, extra) \
((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
@ -670,10 +692,13 @@ void *
pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
pixman_bool_t
pixman_multiply_overflows_int (unsigned int a, unsigned int b);
_pixman_multiply_overflows_size (size_t a, size_t b);
pixman_bool_t
pixman_addition_overflows_int (unsigned int a, unsigned int b);
_pixman_multiply_overflows_int (unsigned int a, unsigned int b);
pixman_bool_t
_pixman_addition_overflows_int (unsigned int a, unsigned int b);
/* Compositing utilities */
void
@ -687,6 +712,17 @@ pixman_contract (uint32_t * dst,
const uint64_t *src,
int width);
pixman_bool_t
_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
pixman_op_t op,
pixman_format_code_t src_format,
uint32_t src_flags,
pixman_format_code_t mask_format,
uint32_t mask_flags,
pixman_format_code_t dest_format,
uint32_t dest_flags,
pixman_implementation_t **out_imp,
pixman_composite_func_t *out_func);
/* Region Helpers */
pixman_bool_t
@ -742,6 +778,7 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
/* Trivial versions that are useful in macros */
#define CONVERT_8888_TO_8888(s) (s)
#define CONVERT_x888_TO_8888(s) ((s) | 0xff000000)
#define CONVERT_0565_TO_0565(s) (s)
#define PIXMAN_FORMAT_IS_WIDE(f) \
@ -758,6 +795,49 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
#endif
static force_inline uint32_t
unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
{
uint32_t result;
if (from_bits == 0)
return 0;
/* Delete any extra bits */
val &= ((1 << from_bits) - 1);
if (from_bits >= to_bits)
return val >> (from_bits - to_bits);
/* Start out with the high bit of val in the high bit of result. */
result = val << (to_bits - from_bits);
/* Copy the bits in result, doubling the number of bits each time, until
* we fill all to_bits. Unrolled manually because from_bits and to_bits
* are usually known statically, so the compiler can turn all of this
* into a few shifts.
*/
#define REPLICATE() \
do \
{ \
if (from_bits < to_bits) \
{ \
result |= result >> from_bits; \
\
from_bits *= 2; \
} \
} \
while (0)
REPLICATE();
REPLICATE();
REPLICATE();
REPLICATE();
REPLICATE();
return result;
}
/*
* Various debugging code
*/
@ -856,10 +936,11 @@ _pixman_log_error (const char *function, const char *message);
static inline uint64_t
oil_profile_stamp_rdtsc (void)
{
uint64_t ts;
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc\n" : "=A" (ts));
return ts;
__asm__ __volatile__ ("rdtsc\n" : "=a" (lo), "=d" (hi));
return lo | (((uint64_t)hi) << 32);
}
#define OIL_STAMP oil_profile_stamp_rdtsc

Просмотреть файл

@ -78,11 +78,11 @@ radial_compute_color (double a,
{
/*
* In this function error propagation can lead to bad results:
* - det can have an unbound error (if b*b-a*c is very small),
* - discr can have an unbound error (if b*b-a*c is very small),
* potentially making it the opposite sign of what it should have been
* (thus clearing a pixel that would have been colored or vice-versa)
* or propagating the error to sqrtdet;
* if det has the wrong sign or b is very small, this can lead to bad
* or propagating the error to sqrtdiscr;
* if discr has the wrong sign or b is very small, this can lead to bad
* results
*
* - the algorithm used to compute the solutions of the quadratic
@ -92,7 +92,7 @@ radial_compute_color (double a,
*
* - the above problems are worse if a is small (as inva becomes bigger)
*/
double det;
double discr;
if (a == 0)
{
@ -116,15 +116,26 @@ radial_compute_color (double a,
return 0;
}
det = fdot (b, a, 0, b, -c, 0);
if (det >= 0)
discr = fdot (b, a, 0, b, -c, 0);
if (discr >= 0)
{
double sqrtdet, t0, t1;
double sqrtdiscr, t0, t1;
sqrtdet = sqrt (det);
t0 = (b + sqrtdet) * inva;
t1 = (b - sqrtdet) * inva;
sqrtdiscr = sqrt (discr);
t0 = (b + sqrtdiscr) * inva;
t1 = (b - sqrtdiscr) * inva;
/*
* The root that must be used is the biggest one that belongs
* to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any
* solution that results in a positive radius otherwise).
*
* If a > 0, t0 is the biggest solution, so if it is valid, it
* is the correct result.
*
* If a < 0, only one of the solutions can be valid, so the
* order in which they are tested is not important.
*/
if (repeat == PIXMAN_REPEAT_NONE)
{
if (0 <= t0 && t0 <= pixman_fixed_1)
@ -151,7 +162,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
* Implementation of radial gradients following the PDF specification.
* See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
* Manual (PDF 32000-1:2008 at the time of this writing).
*
*
* In the radial gradient problem we are given two circles (c,r) and
* (c,r) that define the gradient itself.
*
@ -168,7 +179,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
*
* The graphical result is the same as drawing the valid (radius > 0)
* circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
* is not repeated) using SOURCE operatior composition.
* is not repeated) using SOURCE operator composition.
*
* It looks like a cone pointing towards the viewer if the ending circle
* is smaller than the starting one, a cone pointing inside the page if
@ -179,14 +190,14 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
* in, compute the t values for that point, solving for t in:
*
* length((1-t)·c + t·(c) - p) = (1-t)·r + t·r
*
*
* Let's rewrite it in a simpler way, by defining some auxiliary
* variables:
*
* cd = c - c
* pd = p - c
* dr = r - r
* lenght(t·cd - pd) = r + t·dr
* length(t·cd - pd) = r + t·dr
*
* which actually means
*
@ -212,7 +223,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
* B = pdx·cdx + pdy·cdy + r·dr
* C = pdx² + pdy² - r²
* At² - 2Bt + C = 0
*
*
* The solutions (unless the equation degenerates because of A = 0) are:
*
* t = (B ± (B² - A·C)) / A
@ -251,7 +262,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
return iter->buffer;
unit.vector[0] = image->common.transform->matrix[0][0];
unit.vector[1] = image->common.transform->matrix[1][0];
unit.vector[2] = image->common.transform->matrix[2][0];
@ -457,4 +468,3 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
return image;
}

Просмотреть файл

@ -102,7 +102,11 @@
static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 };
#if defined (__llvm__) && !defined (__clang__)
static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
#else
static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
#endif
static box_type_t *pixman_region_empty_box =
(box_type_t *)&PREFIX (_empty_box_);
@ -824,8 +828,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
{
if (!pixman_rect_alloc (new_reg, new_size))
{
if (old_data)
free (old_data);
free (old_data);
return FALSE;
}
}
@ -1001,8 +1004,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
APPEND_REGIONS (new_reg, r2_band_end, r2_end);
}
if (old_data)
free (old_data);
free (old_data);
if (!(numRects = new_reg->data->numRects))
{
@ -1023,8 +1025,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
return TRUE;
bail:
if (old_data)
free (old_data);
free (old_data);
return pixman_break (new_reg);
}
@ -2086,6 +2087,40 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
return TRUE;
}
/* In time O(log n), locate the first box whose y2 is greater than y.
* Return @end if no such box exists.
*/
static box_type_t *
find_box_for_y (box_type_t *begin, box_type_t *end, int y)
{
box_type_t *mid;
if (end == begin)
return end;
if (end - begin == 1)
{
if (begin->y2 > y)
return begin;
else
return end;
}
mid = begin + (end - begin) / 2;
if (mid->y2 > y)
{
/* If no box is found in [begin, mid], the function
* will return @mid, which is then known to be the
* correct answer.
*/
return find_box_for_y (begin, mid, y);
}
else
{
return find_box_for_y (mid, end, y);
}
}
/*
* rect_in(region, rect)
* This routine takes a pointer to a region and a pointer to a box
@ -2102,7 +2137,6 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
* partially in the region) or is outside the region (we reached a band
* that doesn't overlap the box at all and part_in is false)
*/
pixman_region_overlap_t
PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
box_type_t * prect)
@ -2139,12 +2173,15 @@ PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
/* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */
for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
pbox != pbox_end;
pbox++)
pbox != pbox_end;
pbox++)
{
if (pbox->y2 <= y)
continue; /* getting up to speed or skipping remainder of band */
/* getting up to speed or skipping remainder of band */
if (pbox->y2 <= y)
{
if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end)
break;
}
if (pbox->y1 > y)
{
@ -2319,6 +2356,16 @@ PREFIX (_reset) (region_type_t *region, box_type_t *box)
region->data = NULL;
}
PIXMAN_EXPORT void
PREFIX (_clear) (region_type_t *region)
{
GOOD (region);
FREE_DATA (region);
region->extents = *pixman_region_empty_box;
region->data = pixman_region_empty_data;
}
/* box is "return" value */
PIXMAN_EXPORT int
PREFIX (_contains_point) (region_type_t * region,
@ -2342,13 +2389,13 @@ PREFIX (_contains_point) (region_type_t * region,
return(TRUE);
}
for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
pbox != pbox_end;
pbox++)
{
if (y >= pbox->y2)
continue; /* not there yet */
pbox = PIXREGION_BOXPTR (region);
pbox_end = pbox + numRects;
pbox = find_box_for_y (pbox, pbox_end, y);
for (;pbox != pbox_end; pbox++)
{
if ((y < pbox->y1) || (x < pbox->x1))
break; /* missed it */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -139,7 +139,7 @@ _pixman_edge_multi_init (pixman_edge_t * e,
if (ne > 0)
{
int nx = ne / e->dy;
ne -= nx * e->dy;
ne -= nx * (pixman_fixed_48_16_t)e->dy;
stepx += nx * e->signdx;
}

Просмотреть файл

@ -27,19 +27,136 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "pixman-private.h"
#define N_CACHED_FAST_PATHS 8
typedef struct
{
struct
{
pixman_implementation_t * imp;
pixman_fast_path_t fast_path;
} cache [N_CACHED_FAST_PATHS];
} cache_t;
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
pixman_bool_t
pixman_multiply_overflows_int (unsigned int a,
unsigned int b)
_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
pixman_op_t op,
pixman_format_code_t src_format,
uint32_t src_flags,
pixman_format_code_t mask_format,
uint32_t mask_flags,
pixman_format_code_t dest_format,
uint32_t dest_flags,
pixman_implementation_t **out_imp,
pixman_composite_func_t *out_func)
{
pixman_implementation_t *imp;
cache_t *cache;
int i;
/* Check cache for fast paths */
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
{
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
/* Note that we check for equality here, not whether
* the cached fast path matches. This is to prevent
* us from selecting an overly general fast path
* when a more specific one would work.
*/
if (info->op == op &&
info->src_format == src_format &&
info->mask_format == mask_format &&
info->dest_format == dest_format &&
info->src_flags == src_flags &&
info->mask_flags == mask_flags &&
info->dest_flags == dest_flags &&
info->func)
{
*out_imp = cache->cache[i].imp;
*out_func = cache->cache[i].fast_path.func;
goto update_cache;
}
}
for (imp = toplevel; imp != NULL; imp = imp->delegate)
{
const pixman_fast_path_t *info = imp->fast_paths;
while (info->op != PIXMAN_OP_NONE)
{
if ((info->op == op || info->op == PIXMAN_OP_any) &&
/* Formats */
((info->src_format == src_format) ||
(info->src_format == PIXMAN_any)) &&
((info->mask_format == mask_format) ||
(info->mask_format == PIXMAN_any)) &&
((info->dest_format == dest_format) ||
(info->dest_format == PIXMAN_any)) &&
/* Flags */
(info->src_flags & src_flags) == info->src_flags &&
(info->mask_flags & mask_flags) == info->mask_flags &&
(info->dest_flags & dest_flags) == info->dest_flags)
{
*out_imp = imp;
*out_func = info->func;
/* Set i to the last spot in the cache so that the
* move-to-front code below will work
*/
i = N_CACHED_FAST_PATHS - 1;
goto update_cache;
}
++info;
}
}
return FALSE;
update_cache:
if (i)
{
while (i--)
cache->cache[i + 1] = cache->cache[i];
cache->cache[0].imp = *out_imp;
cache->cache[0].fast_path.op = op;
cache->cache[0].fast_path.src_format = src_format;
cache->cache[0].fast_path.src_flags = src_flags;
cache->cache[0].fast_path.mask_format = mask_format;
cache->cache[0].fast_path.mask_flags = mask_flags;
cache->cache[0].fast_path.dest_format = dest_format;
cache->cache[0].fast_path.dest_flags = dest_flags;
cache->cache[0].fast_path.func = *out_func;
}
return TRUE;
}
pixman_bool_t
_pixman_multiply_overflows_size (size_t a, size_t b)
{
return a >= SIZE_MAX / b;
}
pixman_bool_t
_pixman_multiply_overflows_int (unsigned int a, unsigned int b)
{
return a >= INT32_MAX / b;
}
pixman_bool_t
pixman_addition_overflows_int (unsigned int a,
unsigned int b)
_pixman_addition_overflows_int (unsigned int a, unsigned int b)
{
return a > INT32_MAX - b;
}
@ -67,31 +184,6 @@ pixman_malloc_abc (unsigned int a,
return malloc (a * b * c);
}
/*
* Helper routine to expand a color component from 0 < n <= 8 bits to 16
* bits by replication.
*/
static inline uint64_t
expand16 (const uint8_t val, int nbits)
{
/* Start out with the high bit of val in the high bit of result. */
uint16_t result = (uint16_t)val << (16 - nbits);
if (nbits == 0)
return 0;
/* Copy the bits in result, doubling the number of bits each time, until
* we fill all 16 bits.
*/
while (nbits < 16)
{
result |= result >> nbits;
nbits *= 2;
}
return result;
}
/*
* This function expands images from ARGB8 format to ARGB16. To preserve
* precision, it needs to know the original source format. For example, if the
@ -129,15 +221,33 @@ pixman_expand (uint64_t * dst,
for (i = width - 1; i >= 0; i--)
{
const uint32_t pixel = src[i];
const uint8_t a = (pixel >> a_shift) & a_mask,
r = (pixel >> r_shift) & r_mask,
g = (pixel >> g_shift) & g_mask,
b = (pixel >> b_shift) & b_mask;
const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff,
r16 = expand16 (r, r_size),
g16 = expand16 (g, g_size),
b16 = expand16 (b, b_size);
uint8_t a, r, g, b;
uint64_t a16, r16, g16, b16;
if (a_size)
{
a = (pixel >> a_shift) & a_mask;
a16 = unorm_to_unorm (a, a_size, 16);
}
else
{
a16 = 0xffff;
}
if (r_size)
{
r = (pixel >> r_shift) & r_mask;
g = (pixel >> g_shift) & g_mask;
b = (pixel >> b_shift) & b_mask;
r16 = unorm_to_unorm (r, r_size, 16);
g16 = unorm_to_unorm (g, g_size, 16);
b16 = unorm_to_unorm (b, b_size, 16);
}
else
{
r16 = g16 = b16 = 0;
}
dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
}
}

Просмотреть файл

@ -238,7 +238,7 @@ static pixman_bool_t
pixman_compute_composite_region32 (pixman_region32_t * region,
pixman_image_t * src_image,
pixman_image_t * mask_image,
pixman_image_t * dst_image,
pixman_image_t * dest_image,
int32_t src_x,
int32_t src_y,
int32_t mask_x,
@ -255,8 +255,8 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
region->extents.x1 = MAX (region->extents.x1, 0);
region->extents.y1 = MAX (region->extents.y1, 0);
region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
region->data = 0;
@ -271,29 +271,29 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
return FALSE;
}
if (dst_image->common.have_clip_region)
if (dest_image->common.have_clip_region)
{
if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
return FALSE;
}
if (dst_image->common.alpha_map)
if (dest_image->common.alpha_map)
{
if (!pixman_region32_intersect_rect (region, region,
dst_image->common.alpha_origin_x,
dst_image->common.alpha_origin_y,
dst_image->common.alpha_map->width,
dst_image->common.alpha_map->height))
dest_image->common.alpha_origin_x,
dest_image->common.alpha_origin_y,
dest_image->common.alpha_map->width,
dest_image->common.alpha_map->height))
{
return FALSE;
}
if (!pixman_region32_not_empty (region))
return FALSE;
if (dst_image->common.alpha_map->common.have_clip_region)
if (dest_image->common.alpha_map->common.have_clip_region)
{
if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
-dst_image->common.alpha_origin_x,
-dst_image->common.alpha_origin_y))
if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
-dest_image->common.alpha_origin_x,
-dest_image->common.alpha_origin_y))
{
return FALSE;
}
@ -335,340 +335,89 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
return TRUE;
}
static void
walk_region_internal (pixman_implementation_t *imp,
pixman_op_t op,
pixman_image_t * src_image,
pixman_image_t * mask_image,
pixman_image_t * dst_image,
int32_t src_x,
int32_t src_y,
int32_t mask_x,
int32_t mask_y,
int32_t dest_x,
int32_t dest_y,
int32_t width,
int32_t height,
pixman_bool_t src_repeat,
pixman_bool_t mask_repeat,
pixman_region32_t * region,
pixman_composite_func_t composite_rect)
{
int w, h, w_this, h_this;
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
int src_dy = src_y - dest_y;
int src_dx = src_x - dest_x;
int mask_dy = mask_y - dest_y;
int mask_dx = mask_x - dest_x;
const pixman_box32_t *pbox;
int n;
pbox = pixman_region32_rectangles (region, &n);
/* Fast path for non-repeating sources */
if (!src_repeat && !mask_repeat)
{
while (n--)
{
(*composite_rect) (imp, op,
src_image, mask_image, dst_image,
pbox->x1 + src_dx,
pbox->y1 + src_dy,
pbox->x1 + mask_dx,
pbox->y1 + mask_dy,
pbox->x1,
pbox->y1,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
pbox++;
}
return;
}
while (n--)
{
h = pbox->y2 - pbox->y1;
y_src = pbox->y1 + src_dy;
y_msk = pbox->y1 + mask_dy;
y_dst = pbox->y1;
while (h)
{
h_this = h;
w = pbox->x2 - pbox->x1;
x_src = pbox->x1 + src_dx;
x_msk = pbox->x1 + mask_dx;
x_dst = pbox->x1;
if (mask_repeat)
{
y_msk = MOD (y_msk, mask_image->bits.height);
if (h_this > mask_image->bits.height - y_msk)
h_this = mask_image->bits.height - y_msk;
}
if (src_repeat)
{
y_src = MOD (y_src, src_image->bits.height);
if (h_this > src_image->bits.height - y_src)
h_this = src_image->bits.height - y_src;
}
while (w)
{
w_this = w;
if (mask_repeat)
{
x_msk = MOD (x_msk, mask_image->bits.width);
if (w_this > mask_image->bits.width - x_msk)
w_this = mask_image->bits.width - x_msk;
}
if (src_repeat)
{
x_src = MOD (x_src, src_image->bits.width);
if (w_this > src_image->bits.width - x_src)
w_this = src_image->bits.width - x_src;
}
(*composite_rect) (imp, op,
src_image, mask_image, dst_image,
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
w_this, h_this);
w -= w_this;
x_src += w_this;
x_msk += w_this;
x_dst += w_this;
}
h -= h_this;
y_src += h_this;
y_msk += h_this;
y_dst += h_this;
}
pbox++;
}
}
#define N_CACHED_FAST_PATHS 8
typedef struct
{
struct
{
pixman_implementation_t * imp;
pixman_fast_path_t fast_path;
} cache [N_CACHED_FAST_PATHS];
} cache_t;
pixman_fixed_48_16_t x1;
pixman_fixed_48_16_t y1;
pixman_fixed_48_16_t x2;
pixman_fixed_48_16_t y2;
} box_48_16_t;
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
static force_inline pixman_bool_t
lookup_composite_function (pixman_op_t op,
pixman_format_code_t src_format,
uint32_t src_flags,
pixman_format_code_t mask_format,
uint32_t mask_flags,
pixman_format_code_t dest_format,
uint32_t dest_flags,
pixman_implementation_t **out_imp,
pixman_composite_func_t *out_func)
static pixman_bool_t
compute_transformed_extents (pixman_transform_t *transform,
const pixman_box32_t *extents,
box_48_16_t *transformed)
{
pixman_implementation_t *imp;
cache_t *cache;
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
pixman_fixed_t x1, y1, x2, y2;
int i;
/* Check cache for fast paths */
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
if (!transform)
{
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
transformed->x1 = x1;
transformed->y1 = y1;
transformed->x2 = x2;
transformed->y2 = y2;
/* Note that we check for equality here, not whether
* the cached fast path matches. This is to prevent
* us from selecting an overly general fast path
* when a more specific one would work.
*/
if (info->op == op &&
info->src_format == src_format &&
info->mask_format == mask_format &&
info->dest_format == dest_format &&
info->src_flags == src_flags &&
info->mask_flags == mask_flags &&
info->dest_flags == dest_flags &&
info->func)
{
*out_imp = cache->cache[i].imp;
*out_func = cache->cache[i].fast_path.func;
goto update_cache;
}
return TRUE;
}
for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
tx1 = ty1 = INT64_MAX;
tx2 = ty2 = INT64_MIN;
for (i = 0; i < 4; ++i)
{
const pixman_fast_path_t *info = imp->fast_paths;
pixman_fixed_48_16_t tx, ty;
pixman_vector_t v;
while (info->op != PIXMAN_OP_NONE)
{
if ((info->op == op || info->op == PIXMAN_OP_any) &&
/* Formats */
((info->src_format == src_format) ||
(info->src_format == PIXMAN_any)) &&
((info->mask_format == mask_format) ||
(info->mask_format == PIXMAN_any)) &&
((info->dest_format == dest_format) ||
(info->dest_format == PIXMAN_any)) &&
/* Flags */
(info->src_flags & src_flags) == info->src_flags &&
(info->mask_flags & mask_flags) == info->mask_flags &&
(info->dest_flags & dest_flags) == info->dest_flags)
{
*out_imp = imp;
*out_func = info->func;
v.vector[0] = (i & 0x01)? x1 : x2;
v.vector[1] = (i & 0x02)? y1 : y2;
v.vector[2] = pixman_fixed_1;
/* Set i to the last spot in the cache so that the
* move-to-front code below will work
*/
i = N_CACHED_FAST_PATHS - 1;
if (!pixman_transform_point (transform, &v))
return FALSE;
goto update_cache;
}
tx = (pixman_fixed_48_16_t)v.vector[0];
ty = (pixman_fixed_48_16_t)v.vector[1];
++info;
}
if (tx < tx1)
tx1 = tx;
if (ty < ty1)
ty1 = ty;
if (tx > tx2)
tx2 = tx;
if (ty > ty2)
ty2 = ty;
}
return FALSE;
update_cache:
if (i)
{
while (i--)
cache->cache[i + 1] = cache->cache[i];
cache->cache[0].imp = *out_imp;
cache->cache[0].fast_path.op = op;
cache->cache[0].fast_path.src_format = src_format;
cache->cache[0].fast_path.src_flags = src_flags;
cache->cache[0].fast_path.mask_format = mask_format;
cache->cache[0].fast_path.mask_flags = mask_flags;
cache->cache[0].fast_path.dest_format = dest_format;
cache->cache[0].fast_path.dest_flags = dest_flags;
cache->cache[0].fast_path.func = *out_func;
}
transformed->x1 = tx1;
transformed->y1 = ty1;
transformed->x2 = tx2;
transformed->y2 = ty2;
return TRUE;
}
static pixman_bool_t
compute_sample_extents (pixman_transform_t *transform,
pixman_box32_t *extents, int x, int y,
pixman_fixed_t x_off, pixman_fixed_t y_off,
pixman_fixed_t width, pixman_fixed_t height)
{
pixman_fixed_t x1, y1, x2, y2;
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
/* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
if (!transform)
{
tx1 = (pixman_fixed_48_16_t)x1;
ty1 = (pixman_fixed_48_16_t)y1;
tx2 = (pixman_fixed_48_16_t)x2;
ty2 = (pixman_fixed_48_16_t)y2;
}
else
{
int i;
/* Silence GCC */
tx1 = ty1 = tx2 = ty2 = 0;
for (i = 0; i < 4; ++i)
{
pixman_fixed_48_16_t tx, ty;
pixman_vector_t v;
v.vector[0] = (i & 0x01)? x1 : x2;
v.vector[1] = (i & 0x02)? y1 : y2;
v.vector[2] = pixman_fixed_1;
if (!pixman_transform_point (transform, &v))
return FALSE;
tx = (pixman_fixed_48_16_t)v.vector[0];
ty = (pixman_fixed_48_16_t)v.vector[1];
if (i == 0)
{
tx1 = tx;
ty1 = ty;
tx2 = tx;
ty2 = ty;
}
else
{
if (tx < tx1)
tx1 = tx;
if (ty < ty1)
ty1 = ty;
if (tx > tx2)
tx2 = tx;
if (ty > ty2)
ty2 = ty;
}
}
}
/* Expand the source area by a tiny bit so account of different rounding that
* may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
* 0.5 so this won't cause the area computed to be overly pessimistic.
*/
tx1 += x_off - 8 * pixman_fixed_e;
ty1 += y_off - 8 * pixman_fixed_e;
tx2 += x_off + width + 8 * pixman_fixed_e;
ty2 += y_off + height + 8 * pixman_fixed_e;
if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
{
return FALSE;
}
else
{
extents->x1 = pixman_fixed_to_int (tx1);
extents->y1 = pixman_fixed_to_int (ty1);
extents->x2 = pixman_fixed_to_int (tx2) + 1;
extents->y2 = pixman_fixed_to_int (ty2) + 1;
return TRUE;
}
}
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
#define ABS(f) (((f) < 0)? (-(f)) : (f))
#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
static pixman_bool_t
analyze_extent (pixman_image_t *image, int x, int y,
const pixman_box32_t *extents, uint32_t *flags)
analyze_extent (pixman_image_t *image,
const pixman_box32_t *extents,
uint32_t *flags)
{
pixman_transform_t *transform;
pixman_fixed_t *params;
pixman_fixed_t x_off, y_off;
pixman_fixed_t width, height;
pixman_box32_t ex;
pixman_fixed_t *params;
box_48_16_t transformed;
pixman_box32_t exp_extents;
if (!image)
return TRUE;
@ -678,10 +427,10 @@ analyze_extent (pixman_image_t *image, int x, int y,
* check here that the expanded-by-one source
* extents in destination space fits in 16 bits
*/
if (!IS_16BIT (extents->x1 - x - 1) ||
!IS_16BIT (extents->y1 - y - 1) ||
!IS_16BIT (extents->x2 - x + 1) ||
!IS_16BIT (extents->y2 - y + 1))
if (!IS_16BIT (extents->x1 - 1) ||
!IS_16BIT (extents->y1 - 1) ||
!IS_16BIT (extents->x2 + 1) ||
!IS_16BIT (extents->y2 + 1))
{
return FALSE;
}
@ -696,18 +445,16 @@ analyze_extent (pixman_image_t *image, int x, int y,
if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
return FALSE;
#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
extents->x1 - x >= 0 &&
extents->y1 - y >= 0 &&
extents->x2 - x <= image->bits.width &&
extents->y2 - y <= image->bits.height)
if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
extents->x1 >= 0 &&
extents->y1 >= 0 &&
extents->x2 <= image->bits.width &&
extents->y2 <= image->bits.height)
{
*flags |= FAST_PATH_SAMPLES_COVER_CLIP;
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
return TRUE;
}
switch (image->common.filter)
{
case PIXMAN_FILTER_CONVOLUTION:
@ -738,17 +485,6 @@ analyze_extent (pixman_image_t *image, int x, int y,
default:
return FALSE;
}
/* Check whether the non-expanded, transformed extent is entirely within
* the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
*/
ex = *extents;
if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
ex.x1 >= 0 && ex.y1 >= 0 &&
ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
{
*flags |= FAST_PATH_SAMPLES_COVER_CLIP;
}
}
else
{
@ -758,18 +494,58 @@ analyze_extent (pixman_image_t *image, int x, int y,
height = 0;
}
/* Check that the extents expanded by one don't overflow. This ensures that
* compositing functions can simply walk the source space using 16.16
* variables without worrying about overflow.
*/
ex.x1 = extents->x1 - 1;
ex.y1 = extents->y1 - 1;
ex.x2 = extents->x2 + 1;
ex.y2 = extents->y2 + 1;
if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
if (!compute_transformed_extents (transform, extents, &transformed))
return FALSE;
/* Expand the source area by a tiny bit so account of different rounding that
* may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
* 0.5 so this won't cause the area computed to be overly pessimistic.
*/
transformed.x1 -= 8 * pixman_fixed_e;
transformed.y1 -= 8 * pixman_fixed_e;
transformed.x2 += 8 * pixman_fixed_e;
transformed.y2 += 8 * pixman_fixed_e;
if (image->common.type == BITS)
{
if (pixman_fixed_to_int (transformed.x1) >= 0 &&
pixman_fixed_to_int (transformed.y1) >= 0 &&
pixman_fixed_to_int (transformed.x2) < image->bits.width &&
pixman_fixed_to_int (transformed.y2) < image->bits.height)
{
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
}
if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0 &&
pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0 &&
pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
{
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
}
}
/* Check we don't overflow when the destination extents are expanded by one.
* This ensures that compositing functions can simply walk the source space
* using 16.16 variables without worrying about overflow.
*/
exp_extents = *extents;
exp_extents.x1 -= 1;
exp_extents.y1 -= 1;
exp_extents.x2 += 1;
exp_extents.y2 += 1;
if (!compute_transformed_extents (transform, &exp_extents, &transformed))
return FALSE;
if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
!IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
!IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
!IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
{
return FALSE;
}
return TRUE;
}
@ -809,7 +585,7 @@ pixman_image_composite32 (pixman_op_t op,
pixman_format_code_t src_format, mask_format, dest_format;
uint32_t src_flags, mask_flags, dest_flags;
pixman_region32_t region;
pixman_box32_t *extents;
pixman_box32_t extents;
pixman_implementation_t *imp;
pixman_composite_func_t func;
@ -856,48 +632,87 @@ pixman_image_composite32 (pixman_op_t op,
goto out;
}
extents = pixman_region32_extents (&region);
extents = *pixman_region32_extents (&region);
if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
extents.x1 -= dest_x - src_x;
extents.y1 -= dest_y - src_y;
extents.x2 -= dest_x - src_x;
extents.y2 -= dest_y - src_y;
if (!analyze_extent (src, &extents, &src_flags))
goto out;
if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
extents.x1 -= src_x - mask_x;
extents.y1 -= src_y - mask_y;
extents.x2 -= src_x - mask_x;
extents.y2 -= src_y - mask_y;
if (!analyze_extent (mask, &extents, &mask_flags))
goto out;
/* If the clip is within the source samples, and the samples are opaque,
* then the source is effectively opaque.
/* If the clip is within the source samples, and the samples are
* opaque, then the source is effectively opaque.
*/
#define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
#define NEAREST_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
FAST_PATH_NEAREST_FILTER | \
FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
#define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
FAST_PATH_BILINEAR_FILTER | \
FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
if ((src_flags & BOTH) == BOTH)
if ((src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
(src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
{
src_flags |= FAST_PATH_IS_OPAQUE;
if ((mask_flags & BOTH) == BOTH)
}
if ((mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
(mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
{
mask_flags |= FAST_PATH_IS_OPAQUE;
}
/*
* Check if we can replace our operator by a simpler one
* if the src or dest are opaque. The output operator should be
* mathematically equivalent to the source.
*/
op = optimize_operator (op, src_flags, mask_flags, dest_flags);
if (op == PIXMAN_OP_DST)
goto out;
if (lookup_composite_function (op,
src_format, src_flags,
mask_format, mask_flags,
dest_format, dest_flags,
&imp, &func))
if (_pixman_lookup_composite_function (
get_implementation (), op,
src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags,
&imp, &func))
{
walk_region_internal (imp, op,
src, mask, dest,
src_x, src_y, mask_x, mask_y,
dest_x, dest_y,
width, height,
(src_flags & FAST_PATH_SIMPLE_REPEAT),
(mask_flags & FAST_PATH_SIMPLE_REPEAT),
&region, func);
pixman_composite_info_t info;
const pixman_box32_t *pbox;
int n;
info.op = op;
info.src_image = src;
info.mask_image = mask;
info.dest_image = dest;
info.src_flags = src_flags;
info.mask_flags = mask_flags;
info.dest_flags = dest_flags;
pbox = pixman_region32_rectangles (&region, &n);
while (n--)
{
info.src_x = pbox->x1 + src_x - dest_x;
info.src_y = pbox->y1 + src_y - dest_y;
info.mask_x = pbox->x1 + mask_x - dest_x;
info.mask_y = pbox->y1 + mask_y - dest_y;
info.dest_x = pbox->x1;
info.dest_y = pbox->y1;
info.width = pbox->x2 - pbox->x1;
info.height = pbox->y2 - pbox->y1;
func (imp, &info);
pbox++;
}
}
out:
@ -931,8 +746,8 @@ pixman_blt (uint32_t *src_bits,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height)
{
@ -940,7 +755,7 @@ pixman_blt (uint32_t *src_bits,
src_bits, dst_bits, src_stride, dst_stride,
src_bpp, dst_bpp,
src_x, src_y,
dst_x, dst_y,
dest_x, dest_y,
width, height);
}
@ -1294,7 +1109,7 @@ PIXMAN_EXPORT pixman_bool_t
pixman_compute_composite_region (pixman_region16_t * region,
pixman_image_t * src_image,
pixman_image_t * mask_image,
pixman_image_t * dst_image,
pixman_image_t * dest_image,
int16_t src_x,
int16_t src_y,
int16_t mask_x,
@ -1310,7 +1125,7 @@ pixman_compute_composite_region (pixman_region16_t * region,
pixman_region32_init (&r32);
retval = pixman_compute_composite_region32 (
&r32, src_image, mask_image, dst_image,
&r32, src_image, mask_image, dest_image,
src_x, src_y, mask_x, mask_y, dest_x, dest_y,
width, height);

Просмотреть файл

@ -468,6 +468,7 @@ pixman_bool_t pixman_region_equal (pixman_region16_t *reg
pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
void pixman_region_reset (pixman_region16_t *region,
pixman_box16_t *box);
void pixman_region_clear (pixman_region16_t *region);
/*
* 32 bit regions
*/
@ -562,6 +563,7 @@ pixman_bool_t pixman_region32_equal (pixman_region32_t *r
pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region);
void pixman_region32_reset (pixman_region32_t *region,
pixman_box32_t *box);
void pixman_region32_clear (pixman_region32_t *region);
/* Copy / Fill / Misc */
@ -573,8 +575,8 @@ pixman_bool_t pixman_blt (uint32_t *src_bits,
int dst_bpp,
int src_x,
int src_y,
int dst_x,
int dst_y,
int dest_x,
int dest_y,
int width,
int height);
pixman_bool_t pixman_fill (uint32_t *bits,
@ -813,7 +815,7 @@ pixman_bool_t pixman_image_fill_boxes (pixman_op_t
pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
pixman_image_t *src_image,
pixman_image_t *mask_image,
pixman_image_t *dst_image,
pixman_image_t *dest_image,
int16_t src_x,
int16_t src_y,
int16_t mask_x,

Просмотреть файл

@ -0,0 +1,18 @@
commit 3c275c75e381184fb3fa0537c4bfce50b44690e7
Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
Date: Fri Apr 20 00:12:32 2012 -0400
limits
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 2ec2594..de05c0e 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -27,6 +27,7 @@
#endif
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "pixman-private.h"

Просмотреть файл

@ -41,6 +41,7 @@
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "nsDeviceContext.h"
#include "sampler.h"
namespace mozilla {
namespace layers {
@ -115,6 +116,7 @@ ThebesLayerBuffer::DrawBufferQuadrant(gfxContext* aTarget,
void
ThebesLayerBuffer::DrawBufferWithRotation(gfxContext* aTarget, float aOpacity)
{
SAMPLE_LABEL("ThebesLayerBuffer", "DrawBufferWithRotation");
// Draw four quadrants. We could use REPEAT_, but it's probably better
// not to, to be performance-safe.
DrawBufferQuadrant(aTarget, LEFT, TOP, aOpacity);

Просмотреть файл

@ -66,6 +66,7 @@
#include "gfxXlibSurface.h"
#endif
#include "sampler.h"
#include "GLContext.h"
#define PIXMAN_DONT_DEFINE_STDINT
@ -668,6 +669,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
void* aCallbackData,
ReadbackProcessor* aReadback)
{
SAMPLE_LABEL("BasicThebesLayer", "PaintThebes");
NS_ASSERTION(BasicManager()->InDrawing(),
"Can only draw in drawing phase");
nsRefPtr<gfxASurface> targetSurface = aContext->CurrentSurface();
@ -1632,6 +1634,7 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
SAMPLE_LABEL("BasicLayerManager", "EndTranscationInternal");
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
Log();

Просмотреть файл

@ -51,6 +51,7 @@
#include "ShadowLayerChild.h"
#include "gfxipc/ShadowLayerUtils.h"
#include "RenderTrace.h"
#include "sampler.h"
using namespace mozilla::ipc;
@ -258,6 +259,7 @@ ShadowLayerForwarder::PaintedCanvas(ShadowableLayer* aCanvas,
bool
ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
{
SAMPLE_LABEL("ShadowLayerForwarder", "EndTranscation");
RenderTraceScope rendertrace("Foward Transaction", "000091");
NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?");

Просмотреть файл

@ -94,7 +94,7 @@ struct ScopedXFreePtrTraits
static T *empty() { return NULL; }
static void release(T *ptr) { if (ptr!=NULL) XFree(ptr); }
};
SCOPED_TEMPLATE(ScopedXFree, ScopedXFreePtrTraits);
SCOPED_TEMPLATE(ScopedXFree, ScopedXFreePtrTraits)
/**
* On construction, set a graceful X error handler that doesn't crash the application and records X errors.

Просмотреть файл

@ -55,6 +55,7 @@
#include "gfxPattern.h"
#include "gfxPlatform.h"
#include "gfxTeeSurface.h"
#include "sampler.h"
using namespace mozilla;
using namespace mozilla::gfx;
@ -334,6 +335,7 @@ gfxContext::Stroke()
void
gfxContext::Fill()
{
SAMPLE_LABEL("gfxContext", "Fill");
if (mCairo) {
cairo_fill_preserve(mCairo);
} else {
@ -1448,6 +1450,7 @@ gfxContext::Mask(gfxPattern *pattern)
void
gfxContext::Mask(gfxASurface *surface, const gfxPoint& offset)
{
SAMPLE_LABEL("gfxContext", "Mask");
if (mCairo) {
cairo_mask_surface(mCairo, surface->CairoSurface(), offset.x, offset.y);
} else {
@ -1465,6 +1468,7 @@ gfxContext::Mask(gfxASurface *surface, const gfxPoint& offset)
void
gfxContext::Paint(gfxFloat alpha)
{
SAMPLE_LABEL("gfxContext", "Paint");
if (mCairo) {
cairo_paint_with_alpha(mCairo, alpha);
} else {

Просмотреть файл

@ -286,8 +286,9 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedWord *aShapedWord,
positions = positionsArray.get();
}
// Remember that the glyphToChar indices relate to the CoreText line
// not to the beginning of the textRun, the font run, or the stringRange of the glyph run
// Remember that the glyphToChar indices relate to the CoreText line,
// not to the beginning of the textRun, the font run,
// or the stringRange of the glyph run
glyphToChar = ::CTRunGetStringIndicesPtr(aCTRun);
if (!glyphToChar) {
glyphToCharArray = new (std::nothrow) CFIndex[numGlyphs];
@ -298,7 +299,8 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedWord *aShapedWord,
glyphToChar = glyphToCharArray.get();
}
double runWidth = ::CTRunGetTypographicBounds(aCTRun, ::CFRangeMake(0, 0), NULL, NULL, NULL);
double runWidth = ::CTRunGetTypographicBounds(aCTRun, ::CFRangeMake(0, 0),
NULL, NULL, NULL);
nsAutoTArray<gfxTextRun::DetailedGlyph,1> detailedGlyphs;
gfxTextRun::CompressedGlyph g;
@ -351,11 +353,14 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedWord *aShapedWord,
stringRange.length - 1 : 0; // and this char index (in the stringRange of the glyph run)
while (glyphStart < numGlyphs) { // keep finding groups until all glyphs are accounted for
bool inOrder = true;
PRInt32 charEnd = glyphToChar[glyphStart] - stringRange.location;
NS_ASSERTION(charEnd >= 0 && charEnd < stringRange.length,
"glyph-to-char mapping points outside string range");
NS_WARN_IF_FALSE(charEnd >= 0 && charEnd < stringRange.length,
"glyph-to-char mapping points outside string range");
// clamp charEnd to the valid range of the string
charEnd = NS_MAX(charEnd, 0);
charEnd = NS_MIN(charEnd, PRInt32(stringRange.length));
PRInt32 glyphEnd = glyphStart;
PRInt32 charLimit = isRightToLeft ? -1 : stringRange.length;
do {
@ -373,9 +378,19 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedWord *aShapedWord,
}
// find the maximum glyph index covered by the clump so far
for (PRInt32 i = charStart; i != charEnd; i += direction) {
if (charToGlyph[i] != NO_GLYPH) {
glyphEnd = NS_MAX(glyphEnd, charToGlyph[i] + 1); // update extent of glyph range
if (isRightToLeft) {
for (PRInt32 i = charStart; i > charEnd; --i) {
if (charToGlyph[i] != NO_GLYPH) {
// update extent of glyph range
glyphEnd = NS_MAX(glyphEnd, charToGlyph[i] + 1);
}
}
} else {
for (PRInt32 i = charStart; i < charEnd; ++i) {
if (charToGlyph[i] != NO_GLYPH) {
// update extent of glyph range
glyphEnd = NS_MAX(glyphEnd, charToGlyph[i] + 1);
}
}
}
@ -421,8 +436,21 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedWord *aShapedWord,
}
} while (charEnd != charLimit);
NS_ASSERTION(glyphStart < glyphEnd, "character/glyph clump contains no glyphs!");
NS_ASSERTION(charStart != charEnd, "character/glyph contains no characters!");
NS_WARN_IF_FALSE(glyphStart < glyphEnd,
"character/glyph clump contains no glyphs!");
if (glyphStart == glyphEnd) {
++glyphStart; // make progress - avoid potential infinite loop
charStart = charEnd;
continue;
}
NS_WARN_IF_FALSE(charStart != charEnd,
"character/glyph clump contains no characters!");
if (charStart == charEnd) {
glyphStart = glyphEnd; // this is bad - we'll discard the glyph(s),
// as there's nowhere to attach them
continue;
}
// Now charStart..charEnd is a ligature clump, corresponding to glyphStart..glyphEnd;
// Set baseCharIndex to the char we'll actually attach the glyphs to (1st of ligature),

Просмотреть файл

@ -77,6 +77,7 @@
#include "harfbuzz/hb-blob.h"
#include "nsCRT.h"
#include "sampler.h"
#include <algorithm>
@ -1457,6 +1458,7 @@ struct GlyphBuffer {
cairo_glyph_path(aCR, mGlyphBuffer, mNumGlyphs);
} else {
if (aDrawMode & gfxFont::GLYPH_FILL) {
SAMPLE_LABEL("GlyphBuffer", "cairo_show_glyphs");
cairo_show_glyphs(aCR, mGlyphBuffer, mNumGlyphs);
}

Просмотреть файл

@ -102,3 +102,4 @@ gfxRect::Condition()
height = CAIRO_COORD_MAX - y;
}
}

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsRegion.h"
#include "yuv_convert.h"
#include "ycbcr_to_rgb565.h"
#include "sampler.h"
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
@ -292,6 +293,7 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
const gfxRect& aSubimage,
const gfxImageSurface::gfxImageFormat aFormat)
{
SAMPLE_LABEL("gfxUtils", "CreateSamplingRestricedDrawable");
gfxRect userSpaceClipExtents = aContext->GetClipExtents();
// This isn't optimal --- if aContext has a rotation then GetClipExtents
// will have to do a bounding-box computation, and TransformBounds might
@ -424,6 +426,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
const gfxPattern::GraphicsFilter& aFilter,
PRUint32 aImageFlags)
{
SAMPLE_LABEL("gfxUtils", "DrawPixelSnapped");
bool doTile = !aImageRect.Contains(aSourceRect) &&
!(aImageFlags & imgIContainer::FLAG_CLAMP);

Просмотреть файл

@ -1323,18 +1323,12 @@ TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp, JSO
JSMSG_RESERVED_ID, kw->chars);
}
/* The let keyword is reserved on <1.7 */
if (kw->tokentype == TOK_LET) {
return ReportCompileErrorNumber(cx, this, NULL, JSREPORT_ERROR,
JSMSG_RESERVED_ID, kw->chars);
}
/*
* The keyword is not in this version. Treat it as an identifier,
* unless it is yield which we treat as TOK_STRICT_RESERVED by
* falling through to the code below (ES5 forbids it in strict mode).
* unless it is let or yield which we treat as TOK_STRICT_RESERVED by
* falling through to the code below (ES5 forbids them in strict mode).
*/
if (kw->tokentype != TOK_YIELD)
if (kw->tokentype != TOK_LET && kw->tokentype != TOK_YIELD)
return true;
}

Просмотреть файл

@ -9,7 +9,7 @@ function addTestCase( t ) {\
SECTION,\
'(new Date('+d+')).getUTCDay()',\
WeekDay((d)),\
(new Date(foo ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
(new Date(let ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
);\
}\
");

Просмотреть файл

@ -21,7 +21,6 @@ var futureReservedWords =
"export",
"extends",
"import",
"let", // Reserved even for versionless code, contrary to ES5 - see bug 730139
"super",
];
@ -29,6 +28,7 @@ var strictFutureReservedWords =
[
"implements",
"interface",
"let", // enabled: this file doesn't execute as JS1.7
"package",
"private",
"protected",

Просмотреть файл

@ -1,14 +0,0 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var actual = 'No error';
try {
eval("var let = true");
} catch (exc) {
actual = exc + '';
}
reportCompare('SyntaxError: let is a reserved identifier', actual, 'ok');

Просмотреть файл

@ -47,6 +47,7 @@ test();
//-----------------------------------------------------------------------------
yield = 1;
let = 1;
function test()
{
@ -54,9 +55,10 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
function f(yield) { return yield; }
function f(yield, let) { return yield+let; }
var yield = 1;
var let = 1;
function yield() {}

Просмотреть файл

@ -52,7 +52,7 @@ function test()
printBugNumber(BUGNUMBER);
printStatus (summary);
expect = 'SyntaxError: let is a reserved identifier';
expect = 'SyntaxError: invalid for each loop';
try
{
var obj = { };

Просмотреть файл

@ -1265,6 +1265,15 @@ public:
// clears that capture.
static void ClearMouseCapture(nsIFrame* aFrame);
void SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight);
bool IsScrollPositionClampingScrollPortSizeSet() {
return mScrollPositionClampingScrollPortSizeSet;
}
nsSize GetScrollPositionClampingScrollPortSize() {
NS_ASSERTION(mScrollPositionClampingScrollPortSizeSet, "asking for scroll port when its not set?");
return mScrollPositionClampingScrollPortSize;
}
protected:
friend class nsRefreshDriver;
@ -1315,6 +1324,8 @@ protected:
bool mSuppressInterruptibleReflows;
bool mScrollPositionClampingScrollPortSizeSet;
// A list of weak frames. This is a pointer to the last item in the list.
nsWeakFrame* mWeakFrames;
@ -1333,6 +1344,8 @@ protected:
float mXResolution;
float mYResolution;
nsSize mScrollPositionClampingScrollPortSize;
static nsIContent* gKeyDownTarget;
};

Просмотреть файл

@ -831,6 +831,8 @@ PresShell::PresShell()
mYResolution = 1.0;
mViewportOverridden = false;
mScrollPositionClampingScrollPortSizeSet = false;
static bool addedSynthMouseMove = false;
if (!addedSynthMouseMove) {
Preferences::AddBoolVarCache(&sSynthMouseMove,
@ -9147,3 +9149,10 @@ PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const
/* clear = */false);
}
void
nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
{
mScrollPositionClampingScrollPortSizeSet = true;
mScrollPositionClampingScrollPortSize.width = aWidth;
mScrollPositionClampingScrollPortSize.height = aHeight;
}

Просмотреть файл

@ -1645,7 +1645,7 @@ Clamp(nscoord aLower, nscoord aVal, nscoord aUpper)
nsPoint
nsGfxScrollFrameInner::ClampScrollPosition(const nsPoint& aPt) const
{
nsRect range = GetScrollRange();
nsRect range = GetScrollRangeForClamping();
return nsPoint(Clamp(range.x, aPt.x, range.XMost()),
Clamp(range.y, aPt.y, range.YMost()));
}
@ -1971,7 +1971,7 @@ nsGfxScrollFrameInner::RestrictToDevPixels(const nsPoint& aPt,
// pixels. But we also need to make sure that our position remains
// inside the allowed region.
if (aShouldClamp) {
nsRect scrollRange = GetScrollRange();
nsRect scrollRange = GetScrollRangeForClamping();
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
} else {
@ -2326,10 +2326,16 @@ AlignToDevPixelRoundingToZero(nscoord aVal, PRInt32 aAppUnitsPerDevPixel)
nsRect
nsGfxScrollFrameInner::GetScrollRange() const
{
return GetScrollRange(mScrollPort.width, mScrollPort.height);
}
nsRect
nsGfxScrollFrameInner::GetScrollRange(nscoord aWidth, nscoord aHeight) const
{
nsRect range = GetScrolledRect();
range.width -= mScrollPort.width;
range.height -= mScrollPort.height;
range.width -= aWidth;
range.height -= aHeight;
nsPresContext* presContext = mOuter->PresContext();
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
@ -2342,6 +2348,17 @@ nsGfxScrollFrameInner::GetScrollRange() const
return range;
}
nsRect
nsGfxScrollFrameInner::GetScrollRangeForClamping() const
{
nsIPresShell* presShell = mOuter->PresContext()->PresShell();
if (presShell->IsScrollPositionClampingScrollPortSizeSet()) {
nsSize size = presShell->GetScrollPositionClampingScrollPortSize();
return GetScrollRange(size.width, size.height);
}
return GetScrollRange();
}
static void
AdjustForWholeDelta(PRInt32 aDelta, nscoord* aCoord)
{

Просмотреть файл

@ -178,7 +178,12 @@ public:
return pt;
}
nsRect GetScrollRange() const;
// Get the scroll range assuming the scrollport has size (aWidth, aHeight).
nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
protected:
nsRect GetScrollRangeForClamping() const;
public:
nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const;
nsPoint ClampScrollPosition(const nsPoint& aPt) const;
static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);

Просмотреть файл

@ -694,6 +694,9 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 4194304);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
#endif

Просмотреть файл

@ -10,7 +10,7 @@
#endif
>
<uses-sdk android:minSdkVersion="8"
android:targetSdkVersion="11"/>
android:targetSdkVersion="14"/>
#include ../sync/manifests/SyncAndroidManifest_permissions.xml.in

Просмотреть файл

@ -54,8 +54,9 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.RelativeLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.json.JSONArray;
@ -69,10 +70,15 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
private ListView mAutoCompleteList;
private RelativeLayout mValidationMessage;
private TextView mValidationMessageText;
private ImageView mValidationMessageArrow;
private ImageView mValidationMessageArrowInverted;
private static int sAutoCompleteMinWidth = 0;
private static int sAutoCompleteRowHeight = 0;
private static int sValidationMessageHeight = 0;
private static int sValidationTextMarginTop = 0;
private static RelativeLayout.LayoutParams sValidationTextLayoutNormal;
private static RelativeLayout.LayoutParams sValidationTextLayoutInverted;
// Minimum popup width for autocomplete messages
private static final int AUTOCOMPLETE_MIN_WIDTH_IN_DPI = 200;
@ -80,9 +86,11 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
// Height of the autocomplete_list_item TextView
private static final int AUTOCOMPLETE_ROW_HEIGHT_IN_DPI = 32;
// Height of the validation_message_text TextView, plus the top margin set to
// make room for the arrow
private static final int VALIDATION_MESSAGE_HEIGHT_IN_DPI = 58;
// Height of the validation_message_text TextView
private static final int VALIDATION_MESSAGE_HEIGHT_IN_DPI = 50;
// Top margin for the validation_message_text TextView
private static final int VALIDATION_MESSAGE_MARGIN_TOP_IN_DPI = 6;
private static final String LOGTAG = "FormAssistPopup";
@ -177,6 +185,19 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
addView(mValidationMessage);
mValidationMessageText = (TextView) mValidationMessage.findViewById(R.id.validation_message_text);
DisplayMetrics metrics = new DisplayMetrics();
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
sValidationTextMarginTop = (int) (VALIDATION_MESSAGE_MARGIN_TOP_IN_DPI * metrics.density);
sValidationTextLayoutNormal = new RelativeLayout.LayoutParams(mValidationMessageText.getLayoutParams());
sValidationTextLayoutNormal.setMargins(0, sValidationTextMarginTop, 0, 0);
sValidationTextLayoutInverted = new RelativeLayout.LayoutParams(sValidationTextLayoutNormal);
sValidationTextLayoutInverted.setMargins(0, 0, 0, 0);
mValidationMessageArrow = (ImageView) mValidationMessage.findViewById(R.id.validation_message_arrow);
mValidationMessageArrowInverted = (ImageView) mValidationMessage.findViewById(R.id.validation_message_arrow_inverted);
}
mValidationMessageText.setText(validationMessage);
@ -258,6 +279,12 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
int popupTop = top + height;
if (!isAutoComplete) {
mValidationMessageText.setLayoutParams(sValidationTextLayoutNormal);
mValidationMessageArrow.setVisibility(VISIBLE);
mValidationMessageArrowInverted.setVisibility(GONE);
}
// If the popup doesn't fit below the input box, shrink its height, or
// see if we can place it above the input instead.
if ((popupTop + popupHeight) > viewport.height) {
@ -274,6 +301,12 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
popupTop = 0;
popupHeight = top;
}
if (!isAutoComplete) {
mValidationMessageText.setLayoutParams(sValidationTextLayoutInverted);
mValidationMessageArrow.setVisibility(GONE);
mValidationMessageArrowInverted.setVisibility(VISIBLE);
}
}
}

Просмотреть файл

@ -2298,13 +2298,33 @@ abstract public class GeckoApp
// Do a migration run on the first start after an upgrade.
if (!profileMigrator.hasMigrationRun()) {
// Show the "Setting up Fennec" screen if this takes
// a while.
final SetupScreen setupScreen = new SetupScreen(app);
// Don't show unless this take a while.
setupScreen.showDelayed(mMainHandler);
final Runnable startCallback = new Runnable() {
public void run() {
GeckoApp.mAppContext.runOnUiThread(new Runnable() {
public void run() {
setupScreen.show();
}
});
}
};
final Runnable stopCallback = new Runnable() {
public void run() {
GeckoApp.mAppContext.runOnUiThread(new Runnable() {
public void run() {
setupScreen.dismiss();
}
});
}
};
profileMigrator.setLongOperationCallbacks(startCallback,
stopCallback);
profileMigrator.launchPlaces();
setupScreen.dismiss();
long timeDiff = SystemClock.uptimeMillis() - currentTime;
Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");

Просмотреть файл

@ -107,6 +107,9 @@ public class GeckoAppShell
static public final int WPL_STATE_IS_DOCUMENT = 0x00020000;
static public final int WPL_STATE_IS_NETWORK = 0x00040000;
public static final String SHORTCUT_TYPE_WEBAPP = "webapp";
public static final String SHORTCUT_TYPE_BOOKMARK = "bookmark";
static private File sCacheFile = null;
static private int sFreeSpace = -1;
static File sHomeDir = null;
@ -732,7 +735,7 @@ public class GeckoAppShell
// the intent to be launched by the shortcut
Intent shortcutIntent = new Intent();
if (aType.equalsIgnoreCase("webapp")) {
if (aType.equalsIgnoreCase(SHORTCUT_TYPE_WEBAPP)) {
shortcutIntent.setAction(GeckoApp.ACTION_WEBAPP);
shortcutIntent.setData(Uri.parse(aURI));
} else {
@ -748,14 +751,18 @@ public class GeckoAppShell
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aTitle);
else
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aURI);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, getLauncherIcon(aIcon));
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, getLauncherIcon(aIcon, aType));
// Do not allow duplicate items
intent.putExtra("duplicate", false);
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
GeckoApp.mAppContext.sendBroadcast(intent);
}
});
}
static private Bitmap getLauncherIcon(Bitmap aSource) {
static private Bitmap getLauncherIcon(Bitmap aSource, String aType) {
final int kOffset = 6;
final int kRadius = 5;
int kIconSize;
@ -778,9 +785,14 @@ public class GeckoAppShell
Bitmap bitmap = Bitmap.createBitmap(kIconSize, kIconSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
if (aType.equalsIgnoreCase(SHORTCUT_TYPE_WEBAPP)) {
Rect iconBounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(aSource, null, iconBounds, null);
return bitmap;
}
// draw a base color
Paint paint = new Paint();
if (aSource == null) {
float[] hsv = new float[3];
hsv[0] = 32.0f;

Просмотреть файл

@ -132,6 +132,7 @@ public class GeckoEvent {
public int mMetaState, mFlags;
public int mKeyCode, mUnicodeChar;
public int mRepeatCount;
public int mOffset, mCount;
public String mCharacters, mCharactersExtra;
public int mRangeType, mRangeStyles;
@ -203,6 +204,7 @@ public class GeckoEvent {
mFlags = k.getFlags();
mKeyCode = k.getKeyCode();
mUnicodeChar = k.getUnicodeChar();
mRepeatCount = k.getRepeatCount();
mCharacters = k.getCharacters();
}

Просмотреть файл

@ -366,6 +366,7 @@ RES_DRAWABLE_BASE = \
res/drawable/site_security_verified.png \
res/drawable/urlbar_stop.png \
res/drawable/validation_arrow.png \
res/drawable/validation_arrow_inverted.png \
res/drawable/validation_bg.9.png \
res/drawable/bookmarkdefaults_favicon_support.png \
res/drawable/bookmarkdefaults_favicon_addons.png \
@ -421,6 +422,7 @@ RES_DRAWABLE_HDPI = \
res/drawable-hdpi/site_security_verified.png \
res/drawable-hdpi/urlbar_stop.png \
res/drawable-hdpi/validation_arrow.png \
res/drawable-hdpi/validation_arrow_inverted.png \
res/drawable-hdpi/validation_bg.9.png \
$(addprefix res/drawable-hdpi/,$(notdir $(SYNC_RES_DRAWABLE_HDPI))) \
$(NULL)
@ -484,6 +486,7 @@ RES_DRAWABLE_XHDPI_V11 = \
res/drawable-xhdpi-v11/site_security_verified.png \
res/drawable-xhdpi-v11/tabs_button_tail.9.png \
res/drawable-xhdpi-v11/validation_arrow.png \
res/drawable-xhdpi-v11/validation_arrow_inverted.png \
res/drawable-xhdpi-v11/validation_bg.9.png \
$(NULL)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше