зеркало из https://github.com/mozilla/gecko-dev.git
Merge the last green PGO changeset from mozilla-inbound to mozilla-central; a=merge
This commit is contained in:
Коммит
e6273ad5e1
|
@ -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 (®ion);
|
||||
extents = *pixman_region32_extents (®ion);
|
||||
|
||||
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),
|
||||
®ion, 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 (®ion, &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)
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче