merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-10-29 11:49:27 +01:00
commit bc34f8a9a0
197 changed files with 3967 additions and 2662 deletions

View File

@ -350,9 +350,6 @@ AccessibleWrap::get_accValue(
if (IsProxy())
return E_NOTIMPL;
if (xpAccessible->NativeRole() == roles::PASSWORD_TEXT)
return E_ACCESSDENIED;
nsAutoString value;
xpAccessible->Value(value);

View File

@ -7,6 +7,14 @@
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
},
{
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",

View File

@ -734,9 +734,6 @@
; [Browser Chrome Files]
@RESPATH@/chrome/browser@JAREXT@
@RESPATH@/chrome/browser.manifest
@RESPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
@RESPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
@RESPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
@RESPATH@/chrome/toolkit@JAREXT@
@RESPATH@/chrome/toolkit.manifest
#ifdef XP_UNIX

View File

@ -123,7 +123,7 @@ var gContentPane = {
let bundlePreferences = document.getElementById("bundlePreferences");
let params = { permissionType: "desktop-notification" };
params.windowTitle = bundlePreferences.getString("notificationspermissionstitle");
params.introText = bundlePreferences.getString("notificationspermissionstext2");
params.introText = bundlePreferences.getString("notificationspermissionstext3");
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
"resizable=yes", params);

View File

@ -70,7 +70,7 @@
<rows>
<row id="notificationsPolicyRow">
<vbox align="start">
<label id="notificationsPolicy">&notificationsPolicyDesc.label;</label>
<label id="notificationsPolicy">&notificationsPolicyDesc2.label;</label>
</vbox>
<hbox pack="end">
<button id="notificationsPolicyButton" label="&notificationsPolicyButton.label;"

View File

@ -8,7 +8,7 @@
<!ENTITY blockPopups.accesskey "B">
<!ENTITY notificationsPolicy.label "Notifications">
<!ENTITY notificationsPolicyDesc.label "Choose which sites are allowed to show notifications">
<!ENTITY notificationsPolicyDesc2.label "Choose which sites are allowed to receive notifications">
<!ENTITY notificationsPolicyButton.accesskey "h">
<!ENTITY notificationsPolicyButton.label "Choose…">
<!ENTITY notificationsDoNotDisturb.label "Do not disturb me">

View File

@ -25,7 +25,7 @@ addonspermissionstext=You can specify which websites are allowed to install add-
addons_permissions_title=Allowed Sites - Add-ons Installation
popuppermissionstext=You can specify which websites are allowed to open pop-up windows. Type the exact address of the site you want to allow and then click Allow.
popuppermissionstitle=Allowed Sites - Pop-ups
notificationspermissionstext2=Control which websites are always or never allowed to show notifications. If you remove a site, it will need to request permission again.
notificationspermissionstext3=Control which websites are always or never allowed to receive notifications. If you remove a site, it will need to request permission again.
notificationspermissionstitle=Notification Permissions
invalidURI=Please enter a valid hostname
invalidURITitle=Invalid Hostname Entered

View File

@ -80,7 +80,7 @@ var ContentClick = {
// visits across frames should be preserved.
try {
if (!PrivateBrowsingUtils.isWindowPrivate(window))
PlacesUIUtils.markPageAsFollowedLink(href);
PlacesUIUtils.markPageAsFollowedLink(json.href);
} catch (ex) { /* Skip invalid URIs. */ }
}
};

View File

@ -5164,7 +5164,7 @@ fi;
dnl ========================================================
dnl = Apple platform decoder support
dnl ========================================================
if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
if test "$MOZ_WIDGET_TOOLKIT" = "cocoa" || test "$MOZ_WIDGET_TOOLKIT" = "uikit"; then
MOZ_APPLEMEDIA=1
fi

View File

@ -38,7 +38,7 @@ function test_executable_lines() {
do_check_true(!error);
let source = gThreadClient.source(sources[0]);
source.getExecutableLines(function(lines){
do_check_true(arrays_equal([2, 3, 5, 6, 7, 8, 12, 14, 16], lines));
do_check_true(arrays_equal([2, 5, 7, 8, 12, 14, 16], lines));
finishClient(gClient);
});
});

View File

@ -37,6 +37,7 @@
#include "nsIStringBundle.h"
#include "nsIConsoleService.h"
#include "mozilla/dom/CloseEvent.h"
#include "mozilla/net/WebSocketEventService.h"
#include "nsICryptoHash.h"
#include "nsJSUtils.h"
#include "nsIScriptError.h"
@ -240,6 +241,8 @@ public:
mozilla::Mutex mMutex;
bool mWorkerShuttingDown;
RefPtr<WebSocketEventService> mService;
private:
~WebSocketImpl()
{
@ -630,11 +633,8 @@ WebSocketImpl::Disconnect()
// until the end of the method.
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
nsCOMPtr<nsIThread> mainThread;
if (NS_FAILED(NS_GetMainThread(getter_AddRefs(mainThread))) ||
NS_FAILED(NS_ProxyRelease(mainThread, mChannel))) {
NS_WARNING("Failed to proxy release of channel, leaking instead!");
}
NS_ReleaseOnMainThread(mChannel);
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
mWebSocket->DontKeepAliveAnyMore();
mWebSocket->mImpl = nullptr;
@ -769,6 +769,11 @@ WebSocketImpl::OnStart(nsISupports* aContext)
mWebSocket->SetReadyState(WebSocket::OPEN);
mService->WebSocketOpened(mChannel->Serial(),mInnerWindowID,
mWebSocket->mEffectiveURL,
mWebSocket->mEstablishedProtocol,
mWebSocket->mEstablishedExtensions);
// Let's keep the object alive because the webSocket can be CCed in the
// onopen callback.
RefPtr<WebSocket> webSocket = mWebSocket;
@ -1359,6 +1364,12 @@ WebSocket::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
// Let's inform devtools about this new active WebSocket.
webSocket->mImpl->mService->WebSocketCreated(webSocket->mImpl->mChannel->Serial(),
webSocket->mImpl->mInnerWindowID,
webSocket->mURI,
webSocket->mImpl->mRequestedProtocolList);
cws.Done();
return webSocket.forget();
}
@ -1444,6 +1455,8 @@ WebSocketImpl::Init(JSContext* aCx,
AssertIsOnMainThread();
MOZ_ASSERT(aPrincipal);
mService = WebSocketEventService::GetOrCreate();
// We need to keep the implementation alive in case the init disconnects it
// because of some error.
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
@ -1658,6 +1671,8 @@ WebSocketImpl::AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
if (NS_WARN_IF(aRv.Failed())) {
return;
}
mInnerWindowID = aInnerWindowID;
}
//-----------------------------------------------------------------------------
@ -1837,14 +1852,20 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
return NS_OK;
}
uint16_t messageType = nsIWebSocketEventListener::TYPE_STRING;
// Create appropriate JS object for message
JS::Rooted<JS::Value> jsData(aCx);
if (aIsBinary) {
if (mBinaryType == dom::BinaryType::Blob) {
messageType = nsIWebSocketEventListener::TYPE_BLOB;
nsresult rv = nsContentUtils::CreateBlobBuffer(aCx, GetOwner(), aData,
&jsData);
NS_ENSURE_SUCCESS(rv, rv);
} else if (mBinaryType == dom::BinaryType::Arraybuffer) {
messageType = nsIWebSocketEventListener::TYPE_ARRAYBUFFER;
JS::Rooted<JSObject*> arrayBuf(aCx);
nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, aData,
arrayBuf.address());
@ -1864,6 +1885,10 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
jsData.setString(jsString);
}
mImpl->mService->WebSocketMessageAvailable(mImpl->mChannel->Serial(),
mImpl->mInnerWindowID,
aData, messageType);
// create an event that uses the MessageEvent interface,
// which does not bubble, is not cancelable, and has no default action
@ -1883,11 +1908,15 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
nsresult
WebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
uint16_t aCode,
const nsAString &aReason)
const nsAString& aReason)
{
MOZ_ASSERT(mImpl);
AssertIsOnTargetThread();
mImpl->mService->WebSocketClosed(mImpl->mChannel->Serial(),
mImpl->mInnerWindowID,
aWasClean, aCode, aReason);
nsresult rv = CheckInnerWindowCorrectness();
if (NS_FAILED(rv)) {
return NS_OK;

View File

@ -557,13 +557,6 @@ nsDOMAttributeMap::Count() const
return mAttributeCache.Count();
}
uint32_t
nsDOMAttributeMap::Enumerate(AttrCache::EnumReadFunction aFunc,
void *aUserArg) const
{
return mAttributeCache.EnumerateRead(aFunc, aUserArg);
}
size_t
nsDOMAttributeMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{

View File

@ -128,13 +128,7 @@ public:
typedef nsRefPtrHashtable<nsAttrHashKey, Attr> AttrCache;
/**
* Enumerates over the attribute nodess in the map and calls aFunc for each
* one. If aFunc returns PL_DHASH_STOP we'll stop enumerating at that point.
*
* @return The number of attribute nodes that aFunc was called for.
*/
uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
static void BlastSubtreeToPieces(nsINode *aNode);
Element* GetParentObject() const
{

View File

@ -7633,42 +7633,36 @@ nsIDocument::GetCompatMode(nsString& aCompatMode) const
}
}
static void BlastSubtreeToPieces(nsINode *aNode);
PLDHashOperator
BlastFunc(nsAttrHashKey::KeyType aKey, Attr *aData, void* aUserArg)
{
nsCOMPtr<nsIAttribute> *attr =
static_cast<nsCOMPtr<nsIAttribute>*>(aUserArg);
*attr = aData;
NS_ASSERTION(attr->get(),
"non-nsIAttribute somehow made it into the hashmap?!");
return PL_DHASH_STOP;
}
static void
BlastSubtreeToPieces(nsINode *aNode)
void
nsDOMAttributeMap::BlastSubtreeToPieces(nsINode *aNode)
{
if (aNode->IsElement()) {
Element *element = aNode->AsElement();
const nsDOMAttributeMap *map = element->GetAttributeMap();
if (map) {
nsCOMPtr<nsIAttribute> attr;
while (map->Enumerate(BlastFunc, &attr) > 0) {
// This non-standard style of iteration is presumably used because some
// of the code in the loop body can trigger element removal, which
// invalidates the iterator.
while (true) {
auto iter = map->mAttributeCache.ConstIter();
if (iter.Done()) {
break;
}
nsCOMPtr<nsIAttribute> attr = iter.UserData();
NS_ASSERTION(attr.get(),
"non-nsIAttribute somehow made it into the hashmap?!");
BlastSubtreeToPieces(attr);
#ifdef DEBUG
nsresult rv =
#endif
DebugOnly<nsresult> rv =
element->UnsetAttr(attr->NodeInfo()->NamespaceID(),
attr->NodeInfo()->NameAtom(),
false);
// XXX Should we abort here?
NS_ASSERTION(NS_SUCCEEDED(rv), "Uhoh, UnsetAttr shouldn't fail!");
NS_ASSERTION(NS_SUCCEEDED(rv), "Uh-oh, UnsetAttr shouldn't fail!");
}
}
}
@ -7835,7 +7829,7 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
if (rv.Failed()) {
// Disconnect all nodes from their parents, since some have the old document
// as their ownerDocument and some have this as their ownerDocument.
BlastSubtreeToPieces(adoptedNode);
nsDOMAttributeMap::BlastSubtreeToPieces(adoptedNode);
if (!sameDocument && oldDocument) {
uint32_t count = nodesWithProperties.Count();
@ -7864,7 +7858,7 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
if (rv.Failed()) {
// Disconnect all nodes from their parents.
BlastSubtreeToPieces(adoptedNode);
nsDOMAttributeMap::BlastSubtreeToPieces(adoptedNode);
return nullptr;
}

View File

@ -5507,7 +5507,8 @@ nsGlobalWindow::GetScrollBoundaryOuter(Side aSide)
FlushPendingNotifications(Flush_Layout);
if (nsIScrollableFrame *sf = GetScrollFrame()) {
return sf->GetScrollRange().Edge(aSide);
return nsPresContext::
AppUnitsToIntCSSPixels(sf->GetScrollRange().Edge(aSide));
}
return 0;
}
@ -12869,18 +12870,6 @@ nsGlobalWindow::RemoveGamepad(uint32_t aIndex)
mGamepads.Remove(aIndex);
}
// static
PLDHashOperator
nsGlobalWindow::EnumGamepadsForGet(const uint32_t& aKey, Gamepad* aData,
void* aUserArg)
{
nsTArray<RefPtr<Gamepad> >* array =
static_cast<nsTArray<RefPtr<Gamepad> >*>(aUserArg);
array->EnsureLengthAtLeast(aData->Index() + 1);
(*array)[aData->Index()] = aData;
return PL_DHASH_NEXT;
}
void
nsGlobalWindow::GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads)
{
@ -12888,7 +12877,11 @@ nsGlobalWindow::GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads)
aGamepads.Clear();
// mGamepads.Count() may not be sufficient, but it's not harmful.
aGamepads.SetCapacity(mGamepads.Count());
mGamepads.EnumerateRead(EnumGamepadsForGet, &aGamepads);
for (auto iter = mGamepads.Iter(); !iter.Done(); iter.Next()) {
Gamepad* gamepad = iter.UserData();
aGamepads.EnsureLengthAtLeast(gamepad->Index() + 1);
aGamepads[gamepad->Index()] = gamepad;
}
}
already_AddRefed<Gamepad>
@ -12918,22 +12911,15 @@ nsGlobalWindow::HasSeenGamepadInput()
return mHasSeenGamepadInput;
}
// static
PLDHashOperator
nsGlobalWindow::EnumGamepadsForSync(const uint32_t& aKey, Gamepad* aData,
void* aUserArg)
{
RefPtr<GamepadService> gamepadsvc(GamepadService::GetService());
gamepadsvc->SyncGamepadState(aKey, aData);
return PL_DHASH_NEXT;
}
void
nsGlobalWindow::SyncGamepadState()
{
MOZ_ASSERT(IsInnerWindow());
if (mHasSeenGamepadInput) {
mGamepads.EnumerateRead(EnumGamepadsForSync, nullptr);
RefPtr<GamepadService> gamepadsvc(GamepadService::GetService());
for (auto iter = mGamepads.Iter(); !iter.Done(); iter.Next()) {
gamepadsvc->SyncGamepadState(iter.Key(), iter.UserData());
}
}
}
#endif // MOZ_GAMEPAD
@ -12976,9 +12962,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
tmp->mMessageManager.get())->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
}
tmp->mGroupMessageManagers.EnumerateRead(DisconnectGroupMessageManager, nullptr);
tmp->mGroupMessageManagers.Clear();
tmp->DisconnectAndClearGroupMessageManagers();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

View File

@ -763,12 +763,6 @@ public:
void SetHasSeenGamepadInput(bool aHasSeen);
bool HasSeenGamepadInput();
void SyncGamepadState();
static PLDHashOperator EnumGamepadsForSync(const uint32_t& aKey,
mozilla::dom::Gamepad* aData,
void* aUserArg);
static PLDHashOperator EnumGamepadsForGet(const uint32_t& aKey,
mozilla::dom::Gamepad* aData,
void* aUserArg);
#endif
// Inner windows only.
@ -1906,15 +1900,15 @@ public:
static already_AddRefed<nsGlobalChromeWindow> Create(nsGlobalWindow *aOuterWindow);
static PLDHashOperator
DisconnectGroupMessageManager(const nsAString& aKey,
nsIMessageBroadcaster* aMM,
void* aUserArg)
void DisconnectAndClearGroupMessageManagers()
{
if (aMM) {
static_cast<nsFrameMessageManager*>(aMM)->Disconnect();
for (auto iter = mGroupMessageManagers.Iter(); !iter.Done(); iter.Next()) {
nsIMessageBroadcaster* mm = iter.UserData();
if (mm) {
static_cast<nsFrameMessageManager*>(mm)->Disconnect();
}
}
return PL_DHASH_NEXT;
mGroupMessageManagers.Clear();
}
protected:
@ -1931,8 +1925,7 @@ protected:
MOZ_ASSERT(mCleanMessageManager,
"chrome windows may always disconnect the msg manager");
mGroupMessageManagers.EnumerateRead(DisconnectGroupMessageManager, nullptr);
mGroupMessageManagers.Clear();
DisconnectAndClearGroupMessageManagers();
if (mMessageManager) {
static_cast<nsFrameMessageManager *>(

View File

@ -66,15 +66,125 @@ class BlobURLsReporter final : public nsIMemoryReporter
NS_IMETHOD CollectReports(nsIHandleReportCallback* aCallback,
nsISupports* aData, bool aAnonymize) override
{
EnumArg env;
env.mCallback = aCallback;
env.mData = aData;
env.mAnonymize = aAnonymize;
if (gDataTable) {
gDataTable->EnumerateRead(CountCallback, &env);
gDataTable->EnumerateRead(ReportCallback, &env);
if (!gDataTable) {
return NS_OK;
}
nsDataHashtable<nsPtrHashKey<nsIDOMBlob>, uint32_t> refCounts;
// Determine number of URLs per blob, to handle the case where it's > 1.
for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
nsCOMPtr<nsIDOMBlob> blob =
do_QueryInterface(iter.UserData()->mObject);
if (blob) {
refCounts.Put(blob, refCounts.Get(blob) + 1);
}
}
for (auto iter = gDataTable->Iter(); !iter.Done(); iter.Next()) {
nsCStringHashKey::KeyType key = iter.Key();
DataInfo* info = iter.UserData();
nsCOMPtr<nsIDOMBlob> tmp = do_QueryInterface(info->mObject);
RefPtr<mozilla::dom::Blob> blob =
static_cast<mozilla::dom::Blob*>(tmp.get());
if (blob) {
NS_NAMED_LITERAL_CSTRING(desc,
"A blob URL allocated with URL.createObjectURL; the referenced "
"blob cannot be freed until all URLs for it have been explicitly "
"invalidated with URL.revokeObjectURL.");
nsAutoCString path, url, owner, specialDesc;
nsCOMPtr<nsIURI> principalURI;
uint64_t size = 0;
uint32_t refCount = 1;
DebugOnly<bool> blobWasCounted;
blobWasCounted = refCounts.Get(blob, &refCount);
MOZ_ASSERT(blobWasCounted);
MOZ_ASSERT(refCount > 0);
bool isMemoryFile = blob->IsMemoryFile();
if (isMemoryFile) {
ErrorResult rv;
size = blob->GetSize(rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
size = 0;
}
}
path = isMemoryFile ? "memory-blob-urls/" : "file-blob-urls/";
BuildPath(path, key, info, aAnonymize);
if (refCount > 1) {
nsAutoCString addrStr;
addrStr = "0x";
addrStr.AppendInt((uint64_t)(nsIDOMBlob*)blob, 16);
path += " ";
path.AppendInt(refCount);
path += "@";
path += addrStr;
specialDesc = desc;
specialDesc += "\n\nNOTE: This blob (address ";
specialDesc += addrStr;
specialDesc += ") has ";
specialDesc.AppendInt(refCount);
specialDesc += " URLs.";
if (isMemoryFile) {
specialDesc += " Its size is divided ";
specialDesc += refCount > 2 ? "among" : "between";
specialDesc += " them in this report.";
}
}
const nsACString& descString = specialDesc.IsEmpty()
? static_cast<const nsACString&>(desc)
: static_cast<const nsACString&>(specialDesc);
if (isMemoryFile) {
aCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_BYTES,
size / refCount,
descString,
aData);
} else {
aCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_COUNT,
1,
descString,
aData);
}
} else {
// Just report the path for the DOMMediaStream or MediaSource.
nsCOMPtr<mozilla::dom::MediaSource>
ms(do_QueryInterface(info->mObject));
nsAutoCString path;
path = ms ? "media-source-urls/" : "dom-media-stream-urls/";
BuildPath(path, key, info, aAnonymize);
NS_NAMED_LITERAL_CSTRING(desc,
"An object URL allocated with URL.createObjectURL; the referenced "
"data cannot be freed until all URLs for it have been explicitly "
"invalidated with URL.revokeObjectURL.");
aCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_COUNT,
1,
desc,
aData);
}
}
return NS_OK;
}
@ -143,28 +253,6 @@ class BlobURLsReporter final : public nsIMemoryReporter
private:
~BlobURLsReporter() {}
struct EnumArg {
nsIHandleReportCallback* mCallback;
nsISupports* mData;
bool mAnonymize;
nsDataHashtable<nsPtrHashKey<nsIDOMBlob>, uint32_t> mRefCounts;
};
// Determine number of URLs per blob, to handle the case where it's > 1.
static PLDHashOperator CountCallback(nsCStringHashKey::KeyType aKey,
DataInfo* aInfo,
void* aUserArg)
{
EnumArg* envp = static_cast<EnumArg*>(aUserArg);
nsCOMPtr<nsIDOMBlob> blob;
blob = do_QueryInterface(aInfo->mObject);
if (blob) {
envp->mRefCounts.Put(blob, envp->mRefCounts.Get(blob) + 1);
}
return PL_DHASH_NEXT;
}
static void BuildPath(nsAutoCString& path,
nsCStringHashKey::KeyType aKey,
DataInfo* aInfo,
@ -201,112 +289,6 @@ class BlobURLsReporter final : public nsIMemoryReporter
path += url;
}
}
static PLDHashOperator ReportCallback(nsCStringHashKey::KeyType aKey,
DataInfo* aInfo,
void* aUserArg)
{
EnumArg* envp = static_cast<EnumArg*>(aUserArg);
nsCOMPtr<nsIDOMBlob> tmp = do_QueryInterface(aInfo->mObject);
RefPtr<mozilla::dom::Blob> blob = static_cast<mozilla::dom::Blob*>(tmp.get());
if (blob) {
NS_NAMED_LITERAL_CSTRING
(desc, "A blob URL allocated with URL.createObjectURL; the referenced "
"blob cannot be freed until all URLs for it have been explicitly "
"invalidated with URL.revokeObjectURL.");
nsAutoCString path, url, owner, specialDesc;
nsCOMPtr<nsIURI> principalURI;
uint64_t size = 0;
uint32_t refCount = 1;
DebugOnly<bool> blobWasCounted;
blobWasCounted = envp->mRefCounts.Get(blob, &refCount);
MOZ_ASSERT(blobWasCounted);
MOZ_ASSERT(refCount > 0);
bool isMemoryFile = blob->IsMemoryFile();
if (isMemoryFile) {
ErrorResult rv;
size = blob->GetSize(rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
size = 0;
}
}
path = isMemoryFile ? "memory-blob-urls/" : "file-blob-urls/";
BuildPath(path, aKey, aInfo, envp->mAnonymize);
if (refCount > 1) {
nsAutoCString addrStr;
addrStr = "0x";
addrStr.AppendInt((uint64_t)(nsIDOMBlob*)blob, 16);
path += " ";
path.AppendInt(refCount);
path += "@";
path += addrStr;
specialDesc = desc;
specialDesc += "\n\nNOTE: This blob (address ";
specialDesc += addrStr;
specialDesc += ") has ";
specialDesc.AppendInt(refCount);
specialDesc += " URLs.";
if (isMemoryFile) {
specialDesc += " Its size is divided ";
specialDesc += refCount > 2 ? "among" : "between";
specialDesc += " them in this report.";
}
}
const nsACString& descString = specialDesc.IsEmpty()
? static_cast<const nsACString&>(desc)
: static_cast<const nsACString&>(specialDesc);
if (isMemoryFile) {
envp->mCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_BYTES,
size / refCount,
descString,
envp->mData);
}
else {
envp->mCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_COUNT,
1,
descString,
envp->mData);
}
} else {
// Just report the path for the DOMMediaStream or MediaSource.
nsCOMPtr<mozilla::dom::MediaSource> ms(do_QueryInterface(aInfo->mObject));
nsAutoCString path;
path = ms ? "media-source-urls/" : "dom-media-stream-urls/";
BuildPath(path, aKey, aInfo, envp->mAnonymize);
NS_NAMED_LITERAL_CSTRING
(desc, "An object URL allocated with URL.createObjectURL; the referenced "
"data cannot be freed until all URLs for it have been explicitly "
"invalidated with URL.revokeObjectURL.");
envp->mCallback->Callback(EmptyCString(),
path,
KIND_OTHER,
UNITS_COUNT,
1,
desc,
envp->mData);
}
return PL_DHASH_NEXT;
}
};
NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter)

View File

@ -789,37 +789,6 @@ CheckForGhostWindowsEnumerator(nsISupports *aKey, TimeStamp& aTimeStamp,
return PL_DHASH_NEXT;
}
struct GetNonDetachedWindowDomainsEnumeratorData
{
nsTHashtable<nsCStringHashKey> *nonDetachedDomains;
nsIEffectiveTLDService *tldService;
};
static PLDHashOperator
GetNonDetachedWindowDomainsEnumerator(const uint64_t& aId, nsGlobalWindow* aWindow,
void* aClosure)
{
GetNonDetachedWindowDomainsEnumeratorData *data =
static_cast<GetNonDetachedWindowDomainsEnumeratorData*>(aClosure);
// Null outer window implies null top, but calling GetTop() when there's no
// outer window causes us to spew debug warnings.
if (!aWindow->GetOuterWindow() || !aWindow->GetTopInternal()) {
// This window is detached, so we don't care about its domain.
return PL_DHASH_NEXT;
}
nsCOMPtr<nsIURI> uri = GetWindowURI(aWindow);
nsAutoCString domain;
if (uri) {
data->tldService->GetBaseDomain(uri, 0, domain);
}
data->nonDetachedDomains->PutEntry(domain);
return PL_DHASH_NEXT;
}
/**
* Iterate over mDetachedWindows and update it to reflect the current state of
* the world. In particular:
@ -861,10 +830,22 @@ nsWindowMemoryReporter::CheckForGhostWindows(
nsTHashtable<nsCStringHashKey> nonDetachedWindowDomains;
// Populate nonDetachedWindowDomains.
GetNonDetachedWindowDomainsEnumeratorData nonDetachedEnumData =
{ &nonDetachedWindowDomains, tldService };
windowsById->EnumerateRead(GetNonDetachedWindowDomainsEnumerator,
&nonDetachedEnumData);
for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
// Null outer window implies null top, but calling GetTop() when there's no
// outer window causes us to spew debug warnings.
nsGlobalWindow* window = iter.UserData();
if (!window->GetOuterWindow() || !window->GetTopInternal()) {
// This window is detached, so we don't care about its domain.
continue;
}
nsCOMPtr<nsIURI> uri = GetWindowURI(window);
nsAutoCString domain;
if (uri) {
tldService->GetBaseDomain(uri, 0, domain);
}
nonDetachedWindowDomains.PutEntry(domain);
}
// Update mDetachedWindows and write the ghost window IDs into aOutGhostIDs,
// if it's not null.

View File

@ -12,15 +12,20 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const URI = "ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic";
var frameReceivedCounter = 0;
var frameSentCounter = 0;
var webSocketCreatedCounter = 0;
var webSocketOpenedCounter = 0;
var webSocketMessageAvailableCounter = 0;
var webSocketClosedCounter = 0;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var tests = [
{ payload: "Hello world!" },
{ payload: (function() { var buffer = ""; for (var i = 0; i < 120; ++i) buffer += i; return buffer; }()) },
{ payload: "end" },
]
var innerId =
@ -28,12 +33,61 @@ var innerId =
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
ok(innerId, "We have a valid innerWindowID: " + innerId);
var service = Cc["@mozilla.org/websocketframe/service;1"]
.getService(Ci.nsIWebSocketFrameService);
ok(!!service, "We have the nsIWebSocketFrameService");
var service = Cc["@mozilla.org/websocketevent/service;1"]
.getService(Ci.nsIWebSocketEventService);
ok(!!service, "We have the nsIWebSocketEventService");
var listener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebSocketFrameListener]),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebSocketEventListener]),
webSocketCreated: function(aWebSocketSerialID, aURI, aProtocols) {
info("WebSocketCreated");
is(aURI, URI, "URI matches");
is(aProtocols, "frame", "Protocol matches");
webSocketCreatedCounter++;
},
webSocketOpened: function(aWebSocketSerialID, aEffectiveURI, aProtocols, aExtensions) {
info("WebSocketOpened");
is(aEffectiveURI, URI, "EffectiveURI matches");
is(aProtocols, "frame", "Protocol matches");
is(aExtensions, "permessage-deflate", "No extensions");
webSocketOpenedCounter++;
},
webSocketMessageAvailable: function(aWebSocketSerialID, aData, aMessageType) {
info("WebSocketMessageAvailable");
if (tests.length) {
is(aData, tests[0].payload, "Message matches!");
is(aMessageType, Ci.nsIWebSocketEventListener.TYPE_STRING, "The type is 'string'");
webSocketMessageAvailableCounter++;
tests.shift();
if (tests.length) {
ws.send(tests[0].payload);
} else {
ws.send("end");
}
}
},
webSocketClosed: function(aWebSocketSerialID, aWasClean,
aCode, aReason) {
info("WebSocketClosed");
ok(aWasClean, "The socket is closed in a clean state");
is(aCode, 1000, "Exit code 1000");
ok(!aReason.length, "No reason");
webSocketClosedCounter++;
checkListener();
},
frameReceived: function(aWebSocketSerialID, aFrame) {
ok(!!aFrame, "We have received a frame");
@ -48,15 +102,6 @@ var listener = {
is(aFrame.maskBit, false, "Checking maskBit");
is(aFrame.mask, 0, "Checking mask");
is(aFrame.payload, tests[0].payload, "Checking payload: " + aFrame.payload);
} else {
ok(aFrame.timeStamp, "Checking timeStamp: " + aFrame.timeStamp);
is(aFrame.finBit, true, "Checking finBit");
is(aFrame.rsvBit1, false, "Checking rsvBit1");
is(aFrame.rsvBit2, false, "Checking rsvBit2");
is(aFrame.rsvBit3, false, "Checking rsvBit3");
is(aFrame.opCode, aFrame.OPCODE_CLOSE, "Checking opCode");
is(aFrame.maskBit, false, "Checking maskBit");
is(aFrame.mask, 0, "Checking mask");
}
frameReceivedCounter++;
@ -75,15 +120,6 @@ var listener = {
is(aFrame.maskBit, true, "Checking maskBit");
ok(!!aFrame.mask, "Checking mask: " + aFrame.mask);
is(aFrame.payload, tests[0].payload, "Checking payload: " + aFrame.payload);
} else {
ok(aFrame.timeStamp, "Checking timeStamp: " + aFrame.timeStamp);
is(aFrame.finBit, true, "Checking finBit");
is(aFrame.rsvBit1, false, "Checking rsvBit1");
is(aFrame.rsvBit2, false, "Checking rsvBit2");
is(aFrame.rsvBit3, false, "Checking rsvBit3");
is(aFrame.opCode, aFrame.OPCODE_CLOSE, "Checking opCode");
is(aFrame.maskBit, true, "Checking maskBit");
ok(!!aFrame.mask, "Checking mask: " + aFrame.mask);
}
frameSentCounter++;
@ -98,10 +134,14 @@ function checkListener() {
ok(frameReceivedCounter, "We received some frames!");
ok(frameSentCounter, "We sent some frames!");
ok(webSocketCreatedCounter, "We have a create notification");
ok(webSocketOpenedCounter, "We have a open notification");
ok(webSocketMessageAvailableCounter, "We have a messageAvailable notification");
ok(webSocketClosedCounter, "We have a close notification");
SimpleTest.finish();
}
var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic", "frame");
var ws = new WebSocket(URI, "frame");
ws.onopen = function(e) {
info("onopen");
@ -110,18 +150,12 @@ ws.onopen = function(e) {
ws.onclose = function(e) {
info("onclose");
ws.close();
checkListener();
}
ws.onmessage = function(e) {
info("onmessage");
is(e.data, tests[0].payload, "Wrong data");
tests.shift();
if (tests.length) {
ws.send(tests[0].payload);
is(e.data, tests[0].payload, "Wrong data");
}
}

View File

@ -4497,7 +4497,7 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& image,
if (ok) {
NativeSurface texSurf;
texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
texSurf.mFormat = SurfaceFormat::R5G6B5;
texSurf.mFormat = SurfaceFormat::R5G6B5_UINT16;
texSurf.mSize.width = mCurrentVideoSize.width;
texSurf.mSize.height = mCurrentVideoSize.height;
texSurf.mSurface = (void*)((uintptr_t)mVideoTexture);

View File

@ -1943,7 +1943,7 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
case SurfaceFormat::A8:
*format = WebGLTexelFormat::A8;
break;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
*format = WebGLTexelFormat::RGB565;
break;
default:

View File

@ -430,9 +430,10 @@ AppleMP3Reader::SetupDecoder()
// Set output format
#if defined(MOZ_SAMPLE_TYPE_FLOAT32)
outputFormat.mBitsPerChannel = 32;
outputFormat.mFormatFlags =
kLinearPCMFormatFlagIsFloat |
0;
outputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat;
#elif defined(MOZ_SAMPLE_TYPE_S16)
outputFormat.mBitsPerChannel = 32;
outputFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
#else
#error Unknown audio sample type
#endif
@ -506,23 +507,34 @@ AppleMP3Reader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
AutoPinned<MediaResource> resource(mResource.GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
IntervalSet<int64_t> intervals;
for (auto& range : byteRanges) {
intervals += mFilter.NotifyDataArrived(range.Length(), range.mStart);
}
for (const auto& interval : intervals) {
RefPtr<MediaByteBuffer> bytes =
mResource.MediaReadAt(interval.mStart, interval.Length());
resource->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
}
uint64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
LOGD("Updating media duration to %lluus\n", duration);
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(duration);
}
uint64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
LOGD("Updating media duration to %lluus\n", duration);
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(duration);
}
}

View File

@ -387,22 +387,32 @@ DirectShowReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
IntervalSet<int64_t> intervals;
for (auto& range : byteRanges) {
intervals += mFilter.NotifyDataArrived(range.Length(), range.mStart);
}
for (const auto& interval : intervals) {
RefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
resource->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mDuration);
}
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mDuration);
}
}

View File

@ -403,7 +403,7 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
cr, halfWidth,
mFrameWidth, mFrameHeight);
break;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
rv = libyuv::RGB565ToI420(static_cast<uint8*>(map.GetData()),
map.GetStride(),
y, mFrameWidth,

View File

@ -1286,22 +1286,32 @@ void GStreamerReader::NotifyDataArrivedInternal(uint32_t aLength,
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
AutoPinned<MediaResource> resource(mResource.GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
IntervalSet<int64_t> intervals;
for (auto& range : byteRanges) {
intervals += mFilter.NotifyDataArrived(range.Length(), range.mStart);
}
for (const auto& interval : intervals) {
RefPtr<MediaByteBuffer> bytes =
mResource.MediaReadAt(interval.mStart, interval.Length());
resource->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration && mUseParserDuration) {
MOZ_ASSERT(mDecoder);
mLastParserDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
}
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration && mUseParserDuration) {
MOZ_ASSERT(mDecoder);
mLastParserDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
}
}

View File

@ -27,6 +27,7 @@
#include "nsThreadUtils.h"
#include "mozilla/Logging.h"
#include "nsServiceManagerUtils.h"
#include "gfxPlatform.h"
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidBridge.h"
@ -75,13 +76,14 @@ static const char* const gMediaSourceTypes[6] = {
// * Windows Vista and Server 2008 without the optional "Platform Update Supplement"
// * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
// optional "Windows Media Feature Pack"
// 2. If H264 hardware acceleration is not available.
static bool
IsWebMForced()
{
bool mp4supported =
DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"));
return !mp4supported;
bool hwsupported = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
return !mp4supported || !hwsupported;
}
static nsresult

View File

@ -520,10 +520,21 @@ void
MediaCodecReader::NotifyDataArrivedInternal(uint32_t aLength,
int64_t aOffset)
{
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
IntervalSet<int64_t> intervals;
for (auto& range : byteRanges) {
intervals += mFilter.NotifyDataArrived(range.Length(), range.mStart);
}
for (const auto& interval : intervals) {
RefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
resource->MediaReadAt(interval.mStart, interval.Length());
MonitorAutoLock monLock(mParserMonitor);
if (mNextParserPosition == mParsedDataLength &&
mNextParserPosition >= interval.mStart &&

View File

@ -463,21 +463,31 @@ void MediaOmxReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
IntervalSet<int64_t> intervals;
for (auto& range : byteRanges) {
intervals += mFilter.NotifyDataArrived(range.Length(), range.mStart);
}
for (const auto& interval : intervals) {
RefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
resource->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration) {
mLastParserDuration = duration;
decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
}
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration) {
mLastParserDuration = duration;
decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
}
}

View File

@ -241,6 +241,15 @@ PDMFactory::CreatePDMs()
{
RefPtr<PlatformDecoderModule> m;
if (sUseBlankDecoder) {
m = CreateBlankDecoderModule();
StartupPDM(m);
// The Blank PDM SupportsMimeType reports true for all codecs; the creation
// of its decoder is infallible. As such it will be used for all media, we
// can stop creating more PDM from this point.
return;
}
if (sGMPDecoderEnabled) {
m = new GMPDecoderModule();
StartupPDM(m);
@ -282,11 +291,6 @@ PDMFactory::CreatePDMs()
m = new AgnosticDecoderModule();
StartupPDM(m);
if (sUseBlankDecoder) {
m = CreateBlankDecoderModule();
StartupPDM(m);
}
}
bool

View File

@ -397,6 +397,9 @@ AppleATDecoder::SetupDecoder(MediaRawData* aSample)
mOutputFormat.mFormatFlags =
kLinearPCMFormatFlagIsFloat |
0;
#elif defined(MOZ_SAMPLE_TYPE_S16)
mOutputFormat.mBitsPerChannel = 16;
mOutputFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | 0;
#else
# error Unknown audio sample type
#endif

View File

@ -9,9 +9,12 @@
#include "AppleCMLinker.h"
#include "MainThreadUtils.h"
#include "mozilla/ArrayUtils.h"
#include "nsCocoaFeatures.h"
#include "nsDebug.h"
#ifndef MOZ_WIDGET_UIKIT
#include "nsCocoaFeatures.h"
#endif
extern PRLogModuleInfo* GetPDMLog();
#define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
@ -57,7 +60,11 @@ AppleCMLinker::Link()
goto fail;
}
#ifdef MOZ_WIDGET_UIKIT
if (true) {
#else
if (nsCocoaFeatures::OnLionOrLater()) {
#endif
#define LINK_FUNC2(func) \
func = (typeof(func))dlsym(sLink, #func); \
if (!func) { \

View File

@ -14,16 +14,19 @@
#include "mp4_demuxer/H264.h"
#include "MP4Decoder.h"
#include "MediaData.h"
#include "MacIOSurfaceImage.h"
#include "mozilla/ArrayUtils.h"
#include "nsAutoPtr.h"
#include "nsCocoaFeatures.h"
#include "nsThreadUtils.h"
#include "mozilla/Logging.h"
#include "VideoUtils.h"
#include <algorithm>
#include "gfxPlatform.h"
#ifndef MOZ_WIDGET_UIKIT
#include "nsCocoaFeatures.h"
#include "MacIOSurfaceImage.h"
#endif
extern PRLogModuleInfo* GetPDMLog();
#define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
//#define LOG_MEDIA_SHA1
@ -43,8 +46,13 @@ AppleVDADecoder::AppleVDADecoder(const VideoInfo& aConfig,
, mDisplayHeight(aConfig.mDisplay.height)
, mInputIncoming(0)
, mIsShutDown(false)
#ifdef MOZ_WIDGET_UIKIT
, mUseSoftwareImages(true)
, mIs106(false)
#else
, mUseSoftwareImages(false)
, mIs106(!nsCocoaFeatures::OnLionOrLater())
#endif
, mQueuedSamples(0)
, mMonitor("AppleVideoDecoder")
, mIsFlushing(false)
@ -383,6 +391,7 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
} else {
#ifndef MOZ_WIDGET_UIKIT
IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");
@ -404,6 +413,9 @@ AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
aFrameRef.is_sync_point,
aFrameRef.decode_timestamp.ToMicroseconds(),
visible);
#else
MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
#endif
}
if (!data) {
@ -608,6 +620,7 @@ AppleVDADecoder::CreateOutputConfiguration()
&kCFTypeDictionaryValueCallBacks);
}
#ifndef MOZ_WIDGET_UIKIT
// Construct IOSurface Properties
const void* IOSurfaceKeys[] = { MacIOSurfaceLib::kPropIsGlobal };
const void* IOSurfaceValues[] = { kCFBooleanTrue };
@ -638,6 +651,9 @@ AppleVDADecoder::CreateOutputConfiguration()
ArrayLength(outputKeys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
#else
MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
#endif
}
/* static */

View File

@ -790,10 +790,20 @@ media::TimeIntervals WebMReader::GetBuffered()
void WebMReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
{
MOZ_ASSERT(OnTaskQueue());
RefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
NS_ENSURE_TRUE_VOID(bytes);
mBufferedState->NotifyDataArrived(bytes->Elements(), aLength, aOffset);
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
}
for (auto& range : byteRanges) {
RefPtr<MediaByteBuffer> bytes =
resource->MediaReadAt(range.mStart, range.Length());
NS_ENSURE_TRUE_VOID(bytes);
mBufferedState->NotifyDataArrived(bytes->Elements(), aLength, aOffset);
}
}
int WebMReader::GetVideoCodec()

View File

@ -341,13 +341,10 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mPluginFrame = nullptr;
mWidgetCreationComplete = false;
#ifdef XP_MACOSX
memset(&mCGPluginPortCopy, 0, sizeof(NP_CGContext));
mInCGPaintLevel = 0;
mSentInitialTopLevelWindowEvent = false;
mLastWindowIsActive = false;
mLastContentFocused = false;
mLastScaleFactor = 1.0;
mColorProfile = nullptr;
mShouldBlurOnActivate = false;
#endif
mContentFocused = false;
@ -1208,91 +1205,6 @@ void nsPluginInstanceOwner::RemoveFromCARefreshTimer() {
}
}
void nsPluginInstanceOwner::RenderCoreAnimation(CGContextRef aCGContext,
int aWidth, int aHeight)
{
if (aWidth == 0 || aHeight == 0)
return;
if (!mCARenderer) {
mCARenderer = new nsCARenderer();
}
// aWidth and aHeight are in "display pixels". In non-HiDPI modes
// "display pixels" are device pixels. But in HiDPI modes each
// display pixel corresponds to more than one device pixel.
double scaleFactor = 1.0;
GetContentsScaleFactor(&scaleFactor);
if (!mIOSurface ||
(mIOSurface->GetWidth() != (size_t)aWidth ||
mIOSurface->GetHeight() != (size_t)aHeight ||
mIOSurface->GetContentsScaleFactor() != scaleFactor)) {
mIOSurface = nullptr;
// If the renderer is backed by an IOSurface, resize it as required.
mIOSurface = MacIOSurface::CreateIOSurface(aWidth, aHeight, scaleFactor);
if (mIOSurface) {
RefPtr<MacIOSurface> attachSurface = MacIOSurface::LookupSurface(
mIOSurface->GetIOSurfaceID(),
scaleFactor);
if (attachSurface) {
mCARenderer->AttachIOSurface(attachSurface);
} else {
NS_ERROR("IOSurface attachment failed");
mIOSurface = nullptr;
}
}
}
if (!mColorProfile) {
mColorProfile = CreateSystemColorSpace();
}
if (mCARenderer->isInit() == false) {
void *caLayer = nullptr;
nsresult rv = mInstance->GetValueFromPlugin(NPPVpluginCoreAnimationLayer, &caLayer);
if (NS_FAILED(rv) || !caLayer) {
return;
}
// We don't run Flash in-process so we can unconditionally disallow
// the offliner renderer.
mCARenderer->SetupRenderer(caLayer, aWidth, aHeight, scaleFactor,
DISALLOW_OFFLINE_RENDERER);
// Setting up the CALayer requires resetting the painting otherwise we
// get garbage for the first few frames.
FixUpPluginWindow(ePluginPaintDisable);
FixUpPluginWindow(ePluginPaintEnable);
}
CGImageRef caImage = nullptr;
nsresult rt = mCARenderer->Render(aWidth, aHeight, scaleFactor, &caImage);
if (rt == NS_OK && mIOSurface && mColorProfile) {
nsCARenderer::DrawSurfaceToCGContext(aCGContext, mIOSurface, mColorProfile,
0, 0, aWidth, aHeight);
} else if (rt == NS_OK && caImage != nullptr) {
// Significant speed up by resetting the scaling
::CGContextSetInterpolationQuality(aCGContext, kCGInterpolationNone );
::CGContextTranslateCTM(aCGContext, 0, (double) aHeight * scaleFactor);
::CGContextScaleCTM(aCGContext, scaleFactor, -scaleFactor);
::CGContextDrawImage(aCGContext, CGRectMake(0,0,aWidth,aHeight), caImage);
} else {
NS_NOTREACHED("nsCARenderer::Render failure");
}
}
void* nsPluginInstanceOwner::GetPluginPortCopy()
{
if (GetDrawingModel() == NPDrawingModelCoreGraphics ||
GetDrawingModel() == NPDrawingModelCoreAnimation ||
GetDrawingModel() == NPDrawingModelInvalidatingCoreAnimation)
return &mCGPluginPortCopy;
return nullptr;
}
void nsPluginInstanceOwner::SetPluginPort()
{
void* pluginPort = GetPluginPort();
@ -1300,18 +1212,6 @@ void nsPluginInstanceOwner::SetPluginPort()
return;
mPluginWindow->window = pluginPort;
}
void nsPluginInstanceOwner::BeginCGPaint()
{
++mInCGPaintLevel;
}
void nsPluginInstanceOwner::EndCGPaint()
{
--mInCGPaintLevel;
NS_ASSERTION(mInCGPaintLevel >= 0, "Mismatched call to nsPluginInstanceOwner::EndCGPaint()!");
}
#endif
// static
@ -2544,8 +2444,6 @@ nsPluginInstanceOwner::Destroy()
#ifdef XP_MACOSX
RemoveFromCARefreshTimer();
if (mColorProfile)
::CGColorSpaceRelease(mColorProfile);
#endif
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
@ -3136,11 +3034,7 @@ void nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
return;
}
// If we've already set up a CGContext in nsPluginFrame::PaintPlugin(), we
// don't want calls to SetPluginPort() to step on our work.
if (mInCGPaintLevel < 1) {
SetPluginPort();
}
SetPluginPort();
nsIntSize widgetClip = mPluginFrame->GetWidgetlessClipRect().Size();

View File

@ -136,19 +136,9 @@ public:
// This calls into the plugin (NPP_SetWindow) and can run script.
void FixUpPluginWindow(int32_t inPaintState);
void HidePluginWindow();
// Return a pointer to the internal nsPluginPort structure that's used to
// store a copy of plugin port info and to detect when it's been changed.
void* GetPluginPortCopy();
// Set plugin port info in the plugin (in the 'window' member of the
// NPWindow structure passed to the plugin by SetWindow()).
void SetPluginPort();
// Flag when we've set up a Thebes (and CoreGraphics) context in
// nsPluginFrame::PaintPlugin(). We need to know this in
// FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has
// been called from nsPluginFrame::PaintPlugin() when we're using the
// CoreGraphics drawing model).
void BeginCGPaint();
void EndCGPaint();
#else // XP_MACOSX
void UpdateWindowPositionAndClipRect(bool aSetWindow);
void UpdateWindowVisibility(bool aVisible);
@ -293,11 +283,6 @@ private:
RefPtr<nsPluginHost> mPluginHost;
#ifdef XP_MACOSX
NP_CGContext mCGPluginPortCopy;
int32_t mInCGPaintLevel;
RefPtr<MacIOSurface> mIOSurface;
RefPtr<nsCARenderer> mCARenderer;
CGColorSpaceRef mColorProfile;
static nsCOMPtr<nsITimer> *sCATimer;
static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
bool mSentInitialTopLevelWindowEvent;

View File

@ -188,9 +188,6 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
mWsInfo.display = DefaultXDisplay();
#endif
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
#if defined(OS_WIN)
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
#endif // OS_WIN
#if defined(OS_WIN)
InitPopupMenuHook();
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
@ -821,21 +818,6 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
if (WM_NULL == evcopy.event)
return true;
// Painting for win32. SharedSurfacePaint handles everything.
if (mWindow.type == NPWindowTypeDrawable) {
if (evcopy.event == WM_PAINT) {
*handled = SharedSurfacePaint(evcopy);
return true;
}
else if (DoublePassRenderingEvent() == evcopy.event) {
// We'll render to mSharedSurfaceDib first, then render to a cached bitmap
// we store locally. The two passes are for alpha extraction, so the second
// pass must be to a flat white surface in order for things to work.
mAlphaExtract.doublePass = RENDER_BACK_ONE;
*handled = true;
return true;
}
}
*handled = WinlessHandleEvent(evcopy);
return true;
#endif
@ -1296,13 +1278,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
}
break;
case NPWindowTypeDrawable:
mWindow.type = aWindow.type;
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
SetupFlashMsgThrottle();
return SharedSurfaceSetWindow(aWindow);
break;
default:
NS_NOTREACHED("Bad plugin window type.");
return false;
@ -2024,187 +1999,6 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
return handled;
}
/* windowless drawing helpers */
bool
PluginInstanceChild::SharedSurfaceSetWindow(const NPRemoteWindow& aWindow)
{
// If the surfaceHandle is empty, parent is telling us we can reuse our cached
// memory surface and hdc. Otherwise, we need to reset, usually due to a
// expanding plugin port size.
if (!aWindow.surfaceHandle) {
if (!mSharedSurfaceDib.IsValid()) {
return false;
}
}
else {
// Attach to the new shared surface parent handed us.
if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
aWindow.width, aWindow.height, false)))
return false;
// Free any alpha extraction resources if needed. This will be reset
// the next time it's used.
AlphaExtractCacheRelease();
}
// NPRemoteWindow's origin is the origin of our shared dib.
mWindow.x = aWindow.x;
mWindow.y = aWindow.y;
mWindow.width = aWindow.width;
mWindow.height = aWindow.height;
mWindow.type = aWindow.type;
mWindow.window = reinterpret_cast<void*>(mSharedSurfaceDib.GetHDC());
::SetViewportOrgEx(mSharedSurfaceDib.GetHDC(),
-aWindow.x, -aWindow.y, nullptr);
if (mPluginIface->setwindow)
mPluginIface->setwindow(&mData, &mWindow);
return true;
}
void
PluginInstanceChild::SharedSurfaceRelease()
{
mSharedSurfaceDib.Close();
AlphaExtractCacheRelease();
}
/* double pass cache buffer - (rarely) used in cases where alpha extraction
* occurs for windowless plugins. */
bool
PluginInstanceChild::AlphaExtractCacheSetup()
{
AlphaExtractCacheRelease();
mAlphaExtract.hdc = ::CreateCompatibleDC(nullptr);
if (!mAlphaExtract.hdc)
return false;
BITMAPINFOHEADER bmih;
memset((void*)&bmih, 0, sizeof(BITMAPINFOHEADER));
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = mWindow.width;
bmih.biHeight = mWindow.height;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
void* ppvBits = nullptr;
mAlphaExtract.bmp = ::CreateDIBSection(mAlphaExtract.hdc,
(BITMAPINFO*)&bmih,
DIB_RGB_COLORS,
(void**)&ppvBits,
nullptr,
(unsigned long)sizeof(BITMAPINFOHEADER));
if (!mAlphaExtract.bmp)
return false;
DeleteObject(::SelectObject(mAlphaExtract.hdc, mAlphaExtract.bmp));
return true;
}
void
PluginInstanceChild::AlphaExtractCacheRelease()
{
if (mAlphaExtract.bmp)
::DeleteObject(mAlphaExtract.bmp);
if (mAlphaExtract.hdc)
::DeleteObject(mAlphaExtract.hdc);
mAlphaExtract.bmp = nullptr;
mAlphaExtract.hdc = nullptr;
}
void
PluginInstanceChild::UpdatePaintClipRect(RECT* aRect)
{
if (aRect) {
// Update the clip rect on our internal hdc
HRGN clip = ::CreateRectRgnIndirect(aRect);
::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
::DeleteObject(clip);
}
}
int16_t
PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
{
if (!mPluginIface->event)
return false;
RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
switch(mAlphaExtract.doublePass) {
case RENDER_NATIVE:
// pass the internal hdc to the plugin
UpdatePaintClipRect(pRect);
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
return mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
break;
case RENDER_BACK_ONE:
// Handle a double pass render used in alpha extraction for transparent
// plugins. (See nsPluginFrame and gfxWindowsNativeDrawing for details.)
// We render twice, once to the shared dib, and once to a cache which
// we copy back on a second paint. These paints can't be spread across
// multiple rpc messages as delays cause animation frame changes.
if (!mAlphaExtract.bmp && !AlphaExtractCacheSetup()) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
// See gfxWindowsNativeDrawing, color order doesn't have to match.
UpdatePaintClipRect(pRect);
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
// Copy to cache. We render to shared dib so we don't have to call
// setwindow between calls (flash issue).
::BitBlt(mAlphaExtract.hdc,
pRect->left,
pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top,
mSharedSurfaceDib.GetHDC(),
pRect->left,
pRect->top,
SRCCOPY);
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
mAlphaExtract.doublePass = RENDER_NATIVE;
return false;
}
mAlphaExtract.doublePass = RENDER_BACK_TWO;
return true;
break;
case RENDER_BACK_TWO:
// copy our cached surface back
UpdatePaintClipRect(pRect);
::BitBlt(mSharedSurfaceDib.GetHDC(),
pRect->left,
pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top,
mAlphaExtract.hdc,
pRect->left,
pRect->top,
SRCCOPY);
mAlphaExtract.doublePass = RENDER_NATIVE;
return true;
break;
}
return false;
}
/* flash msg throttling helpers */
// Flash has the unfortunate habit of flooding dispatch loops with custom
@ -4049,7 +3843,6 @@ PluginInstanceChild::Destroy()
mCachedElementActor = nullptr;
#if defined(OS_WIN)
SharedSurfaceRelease();
DestroyWinlessPopupSurrogate();
UnhookWinlessFlashThrottle();
DestroyPluginWindow();

View File

@ -427,29 +427,6 @@ private:
*/
nsAutoPtr< nsTHashtable<DeletingObjectEntry> > mDeletingHash;
#if defined(OS_WIN)
private:
// Shared dib rendering management for windowless plugins.
bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow);
int16_t SharedSurfacePaint(NPEvent& evcopy);
void SharedSurfaceRelease();
bool AlphaExtractCacheSetup();
void AlphaExtractCacheRelease();
void UpdatePaintClipRect(RECT* aRect);
private:
enum {
RENDER_NATIVE,
RENDER_BACK_ONE,
RENDER_BACK_TWO
};
gfx::SharedDIBWin mSharedSurfaceDib;
struct {
uint16_t doublePass;
HDC hdc;
HBITMAP bmp;
} mAlphaExtract;
#endif // defined(OS_WIN)
#if defined(MOZ_WIDGET_COCOA)
private:
#if defined(__i386__)

View File

@ -176,7 +176,6 @@ PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
if (why == AbnormalShutdown) {
// If the plugin process crashes, this is the only
// chance we get to destroy resources.
SharedSurfaceRelease();
UnsubclassPluginWindow();
}
#endif
@ -204,7 +203,6 @@ PluginInstanceParent::Destroy()
}
#if defined(OS_WIN)
SharedSurfaceRelease();
UnsubclassPluginWindow();
#endif
@ -949,11 +947,6 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
#if defined(OS_WIN)
// On windowless controls, reset the shared memory surface as needed.
if (mWindowType == NPWindowTypeDrawable) {
// SharedSurfaceSetWindow will take care of NPRemoteWindow.
if (!SharedSurfaceSetWindow(aWindow, window)) {
return NPERR_OUT_OF_MEMORY_ERROR;
}
MaybeCreateChildPopupSurrogate();
} else {
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
@ -1188,23 +1181,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
#if defined(OS_WIN)
if (mWindowType == NPWindowTypeDrawable) {
if (DoublePassRenderingEvent() == npevent->event) {
return CallPaint(npremoteevent, &handled) && handled;
}
switch (npevent->event) {
case WM_PAINT:
{
RECT rect;
SharedSurfaceBeforePaint(rect, npremoteevent);
if (!CallPaint(npremoteevent, &handled)) {
handled = false;
}
SharedSurfaceAfterPaint(npevent);
return handled;
}
break;
case WM_KILLFOCUS:
{
// When the user selects fullscreen mode in Flash video players,
@ -1936,108 +1913,6 @@ PluginInstanceParent::UnsubclassPluginWindow()
* painting: mPluginPort (nsIntRect, saved in SetWindow)
*/
void
PluginInstanceParent::SharedSurfaceRelease()
{
mSharedSurfaceDib.Close();
}
bool
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
NPRemoteWindow& aRemoteWindow)
{
aRemoteWindow.window = 0;
aRemoteWindow.x = aWindow->x;
aRemoteWindow.y = aWindow->y;
aRemoteWindow.width = aWindow->width;
aRemoteWindow.height = aWindow->height;
aRemoteWindow.type = aWindow->type;
nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
// save the the rect location within the browser window.
mPluginPort = newPort;
// move the port to our shared surface origin
newPort.MoveTo(0,0);
// check to see if we have the room in shared surface
if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
// ok to paint
aRemoteWindow.surfaceHandle = 0;
return true;
}
// allocate a new shared surface
SharedSurfaceRelease();
if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
newPort.width, newPort.height, false)))
return false;
// save the new shared surface size we just allocated
mSharedSize = newPort;
base::SharedMemoryHandle handle;
if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(OtherPid(), &handle))) {
return false;
}
aRemoteWindow.surfaceHandle = handle;
return true;
}
void
PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
NPRemoteEvent& npremoteevent)
{
RECT* dr = (RECT*)npremoteevent.event.lParam;
HDC parentHdc = (HDC)npremoteevent.event.wParam;
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
::BitBlt(mSharedSurfaceDib.GetHDC(),
dirtyRect.x,
dirtyRect.y,
dirtyRect.width,
dirtyRect.height,
parentHdc,
dr->left,
dr->top,
SRCCOPY);
// setup the translated dirty rect we'll send to the child
rect.left = dirtyRect.x;
rect.top = dirtyRect.y;
rect.right = dirtyRect.x + dirtyRect.width;
rect.bottom = dirtyRect.y + dirtyRect.height;
npremoteevent.event.wParam = WPARAM(0);
npremoteevent.event.lParam = LPARAM(&rect);
}
void
PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
{
RECT* dr = (RECT*)npevent->lParam;
HDC parentHdc = (HDC)npevent->wParam;
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
// src copy the shared dib into the parent surface we are handed.
::BitBlt(parentHdc,
dr->left,
dr->top,
dirtyRect.width,
dirtyRect.height,
mSharedSurfaceDib.GetHDC(),
dirtyRect.x,
dirtyRect.y,
SRCCOPY);
}
bool
PluginInstanceParent::MaybeCreateAndParentChildPluginWindow()
{

View File

@ -353,11 +353,6 @@ private:
#if defined(OS_WIN)
private:
// Used in rendering windowless plugins in other processes.
bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
void SharedSurfaceAfterPaint(NPEvent* npevent);
void SharedSurfaceRelease();
// Used in handling parent/child forwarding of events.
static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
@ -368,7 +363,6 @@ private:
void MaybeCreateChildPopupSurrogate();
private:
gfx::SharedDIBWin mSharedSurfaceDib;
nsIntRect mPluginPort;
nsIntRect mSharedSize;
HWND mPluginHWND;

View File

@ -54,9 +54,6 @@ NPRemoteWindow::NPRemoteWindow() :
, visualID(0)
, colormap(0)
#endif /* XP_UNIX */
#if defined(XP_WIN)
,surfaceHandle(0)
#endif
#if defined(XP_MACOSX)
,contentsScaleFactor(1.0)
#endif
@ -156,18 +153,5 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
VOID_TO_NPVARIANT(*v);
}
#ifdef XP_WIN
// The private event used for double-pass widgetless plugin rendering.
UINT DoublePassRenderingEvent()
{
static UINT gEventID = 0;
if (!gEventID)
gEventID = ::RegisterWindowMessage(L"MozDoublePassMsg");
return gEventID;
}
#endif
} // namespace plugins
} // namespace mozilla

View File

@ -93,9 +93,6 @@ struct NPRemoteWindow
VisualID visualID;
Colormap colormap;
#endif /* XP_UNIX */
#if defined(XP_WIN)
base::SharedMemoryHandle surfaceHandle;
#endif
#if defined(XP_MACOSX)
double contentsScaleFactor;
#endif
@ -254,11 +251,6 @@ struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
bool mDeleted;
};
#ifdef XP_WIN
// The private event used for double-pass widgetless plugin rendering.
UINT DoublePassRenderingEvent();
#endif
} /* namespace plugins */
} /* namespace mozilla */
@ -345,9 +337,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
aMsg->WriteULong(aParam.visualID);
aMsg->WriteULong(aParam.colormap);
#endif
#if defined(XP_WIN)
WriteParam(aMsg, aParam.surfaceHandle);
#endif
#if defined(XP_MACOSX)
aMsg->WriteDouble(aParam.contentsScaleFactor);
#endif
@ -377,12 +366,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
return false;
#endif
#if defined(XP_WIN)
base::SharedMemoryHandle surfaceHandle;
if (!ReadParam(aMsg, aIter, &surfaceHandle))
return false;
#endif
#if defined(XP_MACOSX)
double contentsScaleFactor;
if (!aMsg->ReadDouble(aIter, &contentsScaleFactor))
@ -400,9 +383,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
aResult->visualID = visualID;
aResult->colormap = colormap;
#endif
#if defined(XP_WIN)
aResult->surfaceHandle = surfaceHandle;
#endif
#if defined(XP_MACOSX)
aResult->contentsScaleFactor = contentsScaleFactor;
#endif

View File

@ -43,10 +43,10 @@ support-files =
[test_bug1092842.html]
skip-if = e10s
[test_cocoa_focus.html]
skip-if = toolkit != "cocoa"
skip-if = toolkit != "cocoa" || e10s # Bug 1194534
support-files = cocoa_focus.html
[test_cocoa_window_focus.html]
skip-if = toolkit != "cocoa"
skip-if = toolkit != "cocoa" || e10s # Bug 1194534
support-files = cocoa_window_focus.html
[test_cookies.html]
[test_copyText.html]

View File

@ -1127,9 +1127,6 @@ this.PushServiceWebSocket = {
return;
}
// Since we've had a successful connection reset the retry fail count.
this._retryFailCount = 0;
let data = {
messageType: "hello",
use_webpush: true,
@ -1196,12 +1193,10 @@ this.PushServiceWebSocket = {
return;
}
// If we are not waiting for a hello message, reset the retry fail count
if (this._currentState != STATE_WAITING_FOR_HELLO) {
debug('Reseting _retryFailCount and _pingIntervalRetryTimes');
this._retryFailCount = 0;
this._pingIntervalRetryTimes = {};
}
// If we receive a message, we know the connection succeeded. Reset the
// connection attempt and ping interval counters.
this._retryFailCount = 0;
this._pingIntervalRetryTimes = {};
let doNotHandle = false;
if ((message === '{}') ||

View File

@ -378,7 +378,11 @@ MockWebSocket.prototype = {
() => this._listener.onServerClose(this._context, statusCode, reason),
() => this._listener.onStop(this._context, Cr.NS_BASE_STREAM_CLOSED)
);
}
},
serverInterrupt(result = Cr.NS_ERROR_NET_RESET) {
waterfall(() => this._listener.onStop(this._context, result));
},
};
/**

View File

@ -0,0 +1,71 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
const userAgentID = '05f7b940-51b6-4b6f-8032-b83ebb577ded';
function run_test() {
do_get_profile();
setPrefs({
userAgentID: userAgentID,
pingInterval: 10000,
retryBaseInterval: 25,
});
run_next_test();
}
add_task(function* test_ws_retry() {
let db = PushServiceWebSocket.newPushDB();
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield db.put({
channelID: '61770ba9-2d57-4134-b949-d40404630d5b',
pushEndpoint: 'https://example.org/push/1',
scope: 'https://example.net/push/1',
version: 1,
originAttributes: '',
quota: Infinity,
});
let alarmDelays = [];
let setAlarm = PushService.setAlarm;
PushService.setAlarm = function(delay) {
alarmDelays.push(delay);
setAlarm.apply(this, arguments);
};
let handshakeDone;
let handshakePromise = new Promise(resolve => handshakeDone = resolve);
PushService.init({
serverURI: "wss://push.example.org/",
networkInfo: new MockDesktopNetworkInfo(),
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
if (alarmDelays.length == 10) {
PushService.setAlarm = setAlarm;
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
status: 200,
uaid: userAgentID,
}));
handshakeDone();
return;
}
this.serverInterrupt();
},
});
},
});
yield waitForPromise(
handshakePromise,
45000,
'Timed out waiting for successful handshake'
);
deepEqual(alarmDelays, [25, 50, 100, 200, 400, 800, 1600, 3200, 6400, 10000],
'Wrong reconnect alarm delays');
});

View File

@ -40,6 +40,7 @@ run-sequentially = This will delete all existing push subscriptions.
[test_webapps_cleardata.js]
[test_updateRecordNoEncryptionKeys_ws.js]
[test_reconnect_retry.js]
[test_retry_ws.js]
#http2 test
[test_resubscribe_4xxCode_http2.js]
[test_resubscribe_5xxCode_http2.js]

View File

@ -1249,7 +1249,7 @@ public:
static bool DoesBackendSupportDataDrawtarget(BackendType aType);
#ifdef XP_MACOSX
#ifdef XP_DARWIN
static already_AddRefed<DrawTarget> CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize);
static already_AddRefed<GlyphRenderingOptions>
CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor);

View File

@ -137,7 +137,7 @@ private:
};
#endif
#ifdef XP_MACOSX
#ifdef XP_DARWIN
/* This is a helper class that let's you borrow a CGContextRef from a
* DrawTargetCG. This is used for drawing themed widgets.
*

View File

@ -3,6 +3,7 @@
* 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 <dlfcn.h>
#include "BorrowedContext.h"
#include "DataSurfaceHelpers.h"
#include "DrawTargetCG.h"
@ -177,6 +178,7 @@ DrawTargetCG::GetType() const
BackendType
DrawTargetCG::GetBackendType() const
{
#ifdef MOZ_WIDGET_COCOA
// It may be worth spliting Bitmap and IOSurface DrawTarget
// into seperate classes.
if (GetContextType(mCg) == CG_CONTEXT_TYPE_IOSURFACE) {
@ -184,15 +186,20 @@ DrawTargetCG::GetBackendType() const
} else {
return BackendType::COREGRAPHICS;
}
#else
return BackendType::COREGRAPHICS;
#endif
}
already_AddRefed<SourceSurface>
DrawTargetCG::Snapshot()
{
if (!mSnapshot) {
#ifdef MOZ_WIDGET_COCOA
if (GetContextType(mCg) == CG_CONTEXT_TYPE_IOSURFACE) {
return MakeAndAddRef<SourceSurfaceCGIOSurfaceContext>(this);
}
#endif
Flush();
mSnapshot = new SourceSurfaceCGBitmapContext(this);
}
@ -1717,12 +1724,14 @@ DrawTargetCG::Init(BackendType aType,
mSize = aSize;
#ifdef MOZ_WIDGET_COCOA
if (aType == BackendType::COREGRAPHICS_ACCELERATED) {
RefPtr<MacIOSurface> ioSurface = MacIOSurface::CreateIOSurface(aSize.width, aSize.height);
mCg = ioSurface->CreateIOSurfaceContext();
// If we don't have the symbol for 'CreateIOSurfaceContext' mCg will be null
// and we will fallback to software below
}
#endif
mFormat = SurfaceFormat::B8G8R8A8;
@ -1820,6 +1829,7 @@ EnsureValidPremultipliedData(CGContextRef aContext)
void
DrawTargetCG::Flush()
{
#ifdef MOZ_WIDGET_COCOA
if (GetContextType(mCg) == CG_CONTEXT_TYPE_IOSURFACE) {
CGContextFlush(mCg);
} else if (GetContextType(mCg) == CG_CONTEXT_TYPE_BITMAP &&
@ -1835,6 +1845,9 @@ DrawTargetCG::Flush()
EnsureValidPremultipliedData(mCg);
mMayContainInvalidPremultipliedData = false;
}
#else
//TODO
#endif
}
bool
@ -1874,7 +1887,9 @@ DrawTargetCG::Init(CGContextRef cgContext, const IntSize &aSize)
mOriginalTransform = CGContextGetCTM(mCg);
mFormat = SurfaceFormat::B8G8R8A8;
#ifdef MOZ_WIDGET_COCOA
if (GetContextType(mCg) == CG_CONTEXT_TYPE_BITMAP) {
#endif
CGColorSpaceRef colorspace;
CGBitmapInfo bitinfo = CGBitmapContextGetBitmapInfo(mCg);
colorspace = CGBitmapContextGetColorSpace (mCg);
@ -1883,7 +1898,9 @@ DrawTargetCG::Init(CGContextRef cgContext, const IntSize &aSize)
} else if ((bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaNoneSkipFirst) {
mFormat = SurfaceFormat::B8G8R8X8;
}
#ifdef MOZ_WIDGET_COCOA
}
#endif
return true;
}
@ -1906,12 +1923,16 @@ DrawTargetCG::CreatePathBuilder(FillRule aFillRule) const
void*
DrawTargetCG::GetNativeSurface(NativeSurfaceType aType)
{
#ifdef MOZ_WIDGET_COCOA
if ((aType == NativeSurfaceType::CGCONTEXT && GetContextType(mCg) == CG_CONTEXT_TYPE_BITMAP) ||
(aType == NativeSurfaceType::CGCONTEXT_ACCELERATED && GetContextType(mCg) == CG_CONTEXT_TYPE_IOSURFACE)) {
return mCg;
} else {
return nullptr;
}
#else
return mCg;
#endif
}
void

View File

@ -6,7 +6,14 @@
#ifndef mozilla_gfx_DrawTargetCG_h
#define mozilla_gfx_DrawTargetCG_h
#ifdef MOZ_WIDGET_COCOA
#include <ApplicationServices/ApplicationServices.h>
#import <OpenGL/OpenGL.h>
#else
#include <CoreGraphics/CoreGraphics.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#endif
#include "2D.h"
#include "Rect.h"

View File

@ -24,8 +24,10 @@
#ifdef CAIRO_HAS_QUARTZ_SURFACE
#include "cairo-quartz.h"
#ifdef MOZ_WIDGET_COCOA
#include <ApplicationServices/ApplicationServices.h>
#endif
#endif
#ifdef CAIRO_HAS_XLIB_SURFACE
#include "cairo-xlib.h"
@ -669,7 +671,7 @@ GfxFormatForCairoSurface(cairo_surface_t* surface)
// xlib is currently the only Cairo backend that creates 16bpp surfaces
if (type == CAIRO_SURFACE_TYPE_XLIB &&
cairo_xlib_surface_get_depth(surface) == 16) {
return SurfaceFormat::R5G6B5;
return SurfaceFormat::R5G6B5_UINT16;
}
#endif
return CairoContentToGfxFormat(cairo_surface_get_content(surface));

View File

@ -23,12 +23,12 @@
#include "ScaledFontWin.h"
#endif
#ifdef XP_MACOSX
#ifdef XP_DARWIN
#include "ScaledFontMac.h"
#endif
#ifdef XP_MACOSX
#ifdef XP_DARWIN
#include "DrawTargetCG.h"
#endif
@ -299,7 +299,7 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
}
break;
}
#elif defined XP_MACOSX
#elif defined XP_DARWIN
case BackendType::COREGRAPHICS:
case BackendType::COREGRAPHICS_ACCELERATED:
{
@ -382,7 +382,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
break;
}
#endif
#ifdef XP_MACOSX
#ifdef XP_DARWIN
case BackendType::COREGRAPHICS:
{
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
@ -489,7 +489,7 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSiz
}
#endif
#endif
#ifdef XP_MACOSX
#ifdef XP_DARWIN
case NativeFontType::MAC_FONT_FACE:
{
return MakeAndAddRef<ScaledFontMac>(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
@ -791,7 +791,7 @@ Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSiz
return retVal.forget();
}
#ifdef XP_MACOSX
#ifdef XP_DARWIN
already_AddRefed<DrawTarget>
Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize)
{

View File

@ -153,7 +153,7 @@ GfxFormatToCairoFormat(SurfaceFormat format)
return CAIRO_FORMAT_RGB24;
case SurfaceFormat::A8:
return CAIRO_FORMAT_A8;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
return CAIRO_FORMAT_RGB16_565;
default:
gfxCriticalError() << "Unknown image format " << (int)format;
@ -169,7 +169,7 @@ GfxFormatToCairoContent(SurfaceFormat format)
case SurfaceFormat::B8G8R8A8:
return CAIRO_CONTENT_COLOR_ALPHA;
case SurfaceFormat::B8G8R8X8:
case SurfaceFormat::R5G6B5: //fall through
case SurfaceFormat::R5G6B5_UINT16: //fall through
return CAIRO_CONTENT_COLOR;
case SurfaceFormat::A8:
return CAIRO_CONTENT_ALPHA;
@ -241,7 +241,7 @@ CairoFormatToGfxFormat(cairo_format_t format)
case CAIRO_FORMAT_A8:
return SurfaceFormat::A8;
case CAIRO_FORMAT_RGB16_565:
return SurfaceFormat::R5G6B5;
return SurfaceFormat::R5G6B5_UINT16;
default:
gfxCriticalError() << "Unknown cairo format " << format;
return SurfaceFormat::UNKNOWN;

View File

@ -30,7 +30,7 @@ GfxFormatToSkiaColorType(SurfaceFormat format)
case SurfaceFormat::B8G8R8X8:
// We probably need to do something here.
return kBGRA_8888_SkColorType;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
return kRGB_565_SkColorType;
case SurfaceFormat::A8:
return kAlpha_8_SkColorType;
@ -47,7 +47,7 @@ SkiaColorTypeToGfxFormat(SkColorType type)
case kBGRA_8888_SkColorType:
return SurfaceFormat::B8G8R8A8;
case kRGB_565_SkColorType:
return SurfaceFormat::R5G6B5;
return SurfaceFormat::R5G6B5_UINT16;
case kAlpha_8_SkColorType:
return SurfaceFormat::A8;
default:
@ -66,7 +66,7 @@ GfxFormatToGrConfig(SurfaceFormat format)
case SurfaceFormat::B8G8R8X8:
// We probably need to do something here.
return kBGRA_8888_GrPixelConfig;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
return kRGB_565_GrPixelConfig;
case SurfaceFormat::A8:
return kAlpha_8_GrPixelConfig;

View File

@ -399,8 +399,8 @@ public:
case SurfaceFormat::R8G8B8X8:
mMessage << "SurfaceFormat::R8G8B8X8";
break;
case SurfaceFormat::R5G6B5:
mMessage << "SurfaceFormat::R5G6B5";
case SurfaceFormat::R5G6B5_UINT16:
mMessage << "SurfaceFormat::R5G6B5_UINT16";
break;
case SurfaceFormat::A8:
mMessage << "SurfaceFormat::A8";

View File

@ -6,10 +6,23 @@
#ifndef MacIOSurface_h__
#define MacIOSurface_h__
#ifdef XP_MACOSX
#ifdef XP_DARWIN
#include <QuartzCore/QuartzCore.h>
#include <CoreVideo/CoreVideo.h>
#include <dlfcn.h>
struct _CGLContextObject;
typedef _CGLContextObject* CGLContextObj;
typedef struct CGContext* CGContextRef;
typedef struct CGImage* CGImageRef;
typedef uint32_t IOSurfaceID;
#ifdef XP_IOS
typedef kern_return_t IOReturn;
typedef int CGLError;
#endif
typedef CFTypeRef IOSurfacePtr;
typedef IOSurfacePtr (*IOSurfaceCreateFunc) (CFDictionaryRef properties);
typedef IOSurfacePtr (*IOSurfaceLookupFunc) (uint32_t io_surface_id);
@ -42,18 +55,16 @@ typedef IOSurfacePtr (*CVPixelBufferGetIOSurfaceFunc)(
typedef OSType (*IOSurfacePixelFormatFunc)(IOSurfacePtr io_surface);
#ifdef XP_MACOSX
#import <OpenGL/OpenGL.h>
#else
#import <OpenGLES/ES2/gl.h>
#endif
#include "2D.h"
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
struct _CGLContextObject;
typedef _CGLContextObject* CGLContextObj;
typedef struct CGContext* CGContextRef;
typedef struct CGImage* CGImageRef;
typedef uint32_t IOSurfaceID;
enum CGContextType {
CG_CONTEXT_TYPE_UNKNOWN = 0,
// These are found by inspection, it's possible they could be changed

View File

@ -6,7 +6,12 @@
#ifndef MOZILLA_GFX_PATHCG_H_
#define MOZILLA_GFX_PATHCG_H_
#ifdef MOZ_WIDGET_COCOA
#include <ApplicationServices/ApplicationServices.h>
#else
#include <CoreGraphics/CoreGraphics.h>
#endif
#include "2D.h"
namespace mozilla {

View File

@ -13,11 +13,16 @@
#include "DrawTargetCG.h"
#include <vector>
#include <dlfcn.h>
#ifdef MOZ_WIDGET_UIKIT
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifdef MOZ_WIDGET_COCOA
// prototype for private API
extern "C" {
CGPathRef CGFontGetGlyphPath(CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph);
};
#endif
namespace mozilla {
@ -81,11 +86,12 @@ ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aT
{
if (aTarget->GetBackendType() == BackendType::COREGRAPHICS ||
aTarget->GetBackendType() == BackendType::COREGRAPHICS_ACCELERATED) {
#ifdef MOZ_WIDGET_COCOA
CGMutablePathRef path = CGPathCreateMutable();
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
// XXX: we could probably fold both of these transforms together to avoid extra work
CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);
CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
@ -97,6 +103,10 @@ ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aT
RefPtr<Path> ret = new PathCG(path, FillRule::FILL_WINDING);
CGPathRelease(path);
return ret.forget();
#else
//TODO: probably want CTFontCreatePathForGlyph
MOZ_CRASH("This needs implemented");
#endif
}
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
@ -108,7 +118,7 @@ ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBui
ScaledFontBase::CopyGlyphsToBuilder(aBuffer, aBuilder, aBackendType, aTransformHint);
return;
}
#ifdef MOZ_WIDGET_COCOA
PathBuilderCG *pathBuilderCG =
static_cast<PathBuilderCG*>(aBuilder);
// XXX: check builder type
@ -123,6 +133,10 @@ ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBui
CGPathAddPath(pathBuilderCG->mCGPath, &matrix, glyphPath);
CGPathRelease(glyphPath);
}
#else
//TODO: probably want CTFontCreatePathForGlyph
MOZ_CRASH("This needs implemented");
#endif
}
uint32_t

View File

@ -6,7 +6,13 @@
#ifndef MOZILLA_GFX_SCALEDFONTMAC_H_
#define MOZILLA_GFX_SCALEDFONTMAC_H_
#import <ApplicationServices/ApplicationServices.h>
#ifdef MOZ_WIDGET_COCOA
#include <ApplicationServices/ApplicationServices.h>
#else
#include <CoreGraphics/CoreGraphics.h>
#include <CoreText/CoreText.h>
#endif
#include "2D.h"
#include "ScaledFontBase.h"

View File

@ -9,7 +9,9 @@
#include "DataSurfaceHelpers.h"
#include "mozilla/Types.h" // for decltype
#ifdef MOZ_WIDGET_COCOA
#include "MacIOSurface.h"
#endif
#include "Tools.h"
namespace mozilla {
@ -384,6 +386,7 @@ SourceSurfaceCGBitmapContext::~SourceSurfaceCGBitmapContext()
CGImageRelease(mImage);
}
#ifdef MOZ_WIDGET_COCOA
SourceSurfaceCGIOSurfaceContext::SourceSurfaceCGIOSurfaceContext(DrawTargetCG *aDrawTarget)
{
CGContextRef cg = (CGContextRef)aDrawTarget->GetNativeSurface(NativeSurfaceType::CGCONTEXT_ACCELERATED);
@ -452,6 +455,7 @@ SourceSurfaceCGIOSurfaceContext::GetData()
{
return (unsigned char*)mData;
}
#endif
} // namespace gfx
} // namespace mozilla

View File

@ -6,11 +6,17 @@
#ifndef _MOZILLA_GFX_SOURCESURFACECG_H
#define _MOZILLA_GFX_SOURCESURFACECG_H
#ifdef MOZ_WIDGET_COCOA
#include <ApplicationServices/ApplicationServices.h>
#else
#include <CoreGraphics/CoreGraphics.h>
#endif
#include "2D.h"
#ifdef MOZ_WIDGET_COCOA
class MacIOSurface;
#endif
namespace mozilla {
namespace gfx {
@ -163,6 +169,7 @@ private:
IntSize mSize;
};
#ifdef MOZ_WIDGET_COCOA
class SourceSurfaceCGIOSurfaceContext : public SourceSurfaceCGContext
{
public:
@ -196,6 +203,7 @@ private:
IntSize mSize;
};
#endif
} // namespace gfx

View File

@ -86,7 +86,7 @@ BytesPerPixel(SurfaceFormat aFormat)
switch (aFormat) {
case SurfaceFormat::A8:
return 1;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
return 2;
default:
return 4;

View File

@ -30,14 +30,28 @@ enum class SurfaceType : int8_t {
};
enum class SurfaceFormat : int8_t {
B8G8R8A8,
B8G8R8X8,
R8G8B8A8,
R8G8B8X8,
R5G6B5,
// The following values are named to reflect layout of colors in memory, from
// lowest byte to highest byte. The 32-bit value layout depends on machine
// endianness.
// in-memory 32-bit LE value 32-bit BE value
B8G8R8A8, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
B8G8R8X8, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
R8G8B8A8, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
R8G8B8X8, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
// The _UINT16 suffix here indicates that the name reflects the layout when
// viewed as a uint16_t value. In memory these values are stored using native
// endianness.
R5G6B5_UINT16, // 0bRRRRRGGGGGGBBBBB
// This one is a single-byte, so endianness isn't an issue.
A8,
// These ones are their own special cases.
YUV,
NV12,
// This represents the unknown format.
UNKNOWN
};
@ -46,7 +60,7 @@ inline bool IsOpaque(SurfaceFormat aFormat)
switch (aFormat) {
case SurfaceFormat::B8G8R8X8:
case SurfaceFormat::R8G8B8X8:
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
case SurfaceFormat::YUV:
case SurfaceFormat::NV12:
return true;

View File

@ -48,10 +48,9 @@ EXPORTS.mozilla.gfx += [
'UserData.h',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
EXPORTS.mozilla.gfx += [
'MacIOSurface.h',
'QuartzSupport.h',
]
UNIFIED_SOURCES += [
'DrawTargetCG.cpp',
@ -160,6 +159,9 @@ SOURCES += [
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXPORTS.mozilla.gfx += [
'QuartzSupport.h',
]
SOURCES += [
'MacIOSurface.cpp',
'QuartzSupport.mm',

View File

@ -77,6 +77,7 @@ static const char *sExtensionNames[] = {
"GL_ANGLE_timer_query",
"GL_APPLE_client_storage",
"GL_APPLE_framebuffer_multisample",
"GL_APPLE_sync",
"GL_APPLE_texture_range",
"GL_APPLE_vertex_array_object",
"GL_ARB_ES2_compatibility",
@ -783,7 +784,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
if (!IsSupported(GLFeature::framebuffer_object)) {
// Check for aux symbols based on extensions
if (IsSupported(GLFeature::framebuffer_object_EXT_OES))
{
@ -811,11 +811,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
if (IsExtensionSupported(GLContext::ANGLE_framebuffer_blit) ||
IsExtensionSupported(GLContext::EXT_framebuffer_blit) ||
IsExtensionSupported(GLContext::NV_framebuffer_blit))
{
if (IsSupported(GLFeature::framebuffer_blit)) {
SymLoadStruct extSymbols[] = {
EXT_SYMBOL3(BlitFramebuffer, ANGLE, EXT, NV),
END_SYMBOLS
@ -826,11 +822,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
if (IsExtensionSupported(GLContext::ANGLE_framebuffer_multisample) ||
IsExtensionSupported(GLContext::APPLE_framebuffer_multisample) ||
IsExtensionSupported(GLContext::EXT_framebuffer_multisample) ||
IsExtensionSupported(GLContext::EXT_multisampled_render_to_texture))
{
if (IsSupported(GLFeature::framebuffer_multisample)) {
SymLoadStruct extSymbols[] = {
EXT_SYMBOL3(RenderbufferStorageMultisample, ANGLE, APPLE, EXT),
END_SYMBOLS
@ -1546,7 +1538,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (IsSupported(GLFeature::read_buffer)) {
SymLoadStruct extSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } },
{ (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } },
END_SYMBOLS
};
@ -1558,6 +1550,20 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
if (IsExtensionSupported(APPLE_framebuffer_multisample)) {
SymLoadStruct extSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fResolveMultisampleFramebufferAPPLE, { "ResolveMultisampleFramebufferAPPLE", nullptr } },
END_SYMBOLS
};
if (!LoadSymbols(&extSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports APPLE_framebuffer_multisample without supplying its functions.");
MarkExtensionUnsupported(APPLE_framebuffer_multisample);
ClearSymbols(extSymbols);
}
}
// Load developer symbols, don't fail if we can't find them.
SymLoadStruct auxSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
@ -2913,7 +2919,7 @@ GLContext::GetReadFB()
if (mScreen)
return mScreen->GetReadFB();
GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit)
GLenum bindEnum = IsSupported(GLFeature::split_framebuffer)
? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
: LOCAL_GL_FRAMEBUFFER_BINDING;

View File

@ -124,6 +124,7 @@ enum class GLFeature {
sRGB_framebuffer,
sRGB_texture,
sampler_objects,
split_framebuffer,
standard_derivatives,
sync,
texture_3D,
@ -390,6 +391,7 @@ public:
ANGLE_timer_query,
APPLE_client_storage,
APPLE_framebuffer_multisample,
APPLE_sync,
APPLE_texture_range,
APPLE_vertex_array_object,
ARB_ES2_compatibility,
@ -3139,6 +3141,16 @@ public:
return ret;
}
// -----------------------------------------------------------------------------
// APPLE_framebuffer_multisample
void fResolveMultisampleFramebufferAPPLE() {
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE);
mSymbols.fResolveMultisampleFramebufferAPPLE();
AFTER_GL_CALL;
}
// -----------------------------------------------------------------------------
// Constructor
protected:

79
gfx/gl/GLContextEAGL.h Normal file
View File

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
/* 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 GLCONTEXTEAGL_H_
#define GLCONTEXTEAGL_H_
#include "GLContext.h"
#include <CoreGraphics/CoreGraphics.h>
#include <OpenGLES/EAGL.h>
namespace mozilla {
namespace gl {
class GLContextEAGL : public GLContext
{
friend class GLContextProviderEAGL;
EAGLContext* const mContext;
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEAGL, override)
GLContextEAGL(const SurfaceCaps& caps, EAGLContext* context,
GLContext* sharedContext,
bool isOffscreen, ContextProfile profile);
~GLContextEAGL();
virtual GLContextType GetContextType() const override {
return GLContextType::EAGL;
}
static GLContextEAGL* Cast(GLContext* gl) {
MOZ_ASSERT(gl->GetContextType() == GLContextType::EAGL);
return static_cast<GLContextEAGL*>(gl);
}
bool Init() override;
bool AttachToWindow(nsIWidget* aWidget);
EAGLContext* GetEAGLContext() const { return mContext; }
virtual bool MakeCurrentImpl(bool aForce) override;
virtual bool IsCurrent() override;
virtual bool SetupLookupFunction() override;
virtual bool IsDoubleBuffered() const override;
virtual bool SupportsRobustness() const override;
virtual bool SwapBuffers() override;
virtual GLuint GetDefaultFramebuffer() override {
return mBackbufferFB;
}
virtual bool RenewSurface() override {
return RecreateRB();
}
private:
GLuint mBackbufferRB;
GLuint mBackbufferFB;
void* mLayer;
bool RecreateRB();
};
} // namespace gl
} // namespace mozilla
#endif // GLCONTEXTEAGL_H_

View File

@ -547,6 +547,20 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End
}
},
{
// Do we have separate DRAW and READ framebuffer bind points?
"split_framebuffer",
GLVersion::GL3,
GLESVersion::ES3,
GLContext::ARB_framebuffer_object,
{
GLContext::ANGLE_framebuffer_blit,
GLContext::APPLE_framebuffer_multisample,
GLContext::EXT_framebuffer_blit,
GLContext::NV_framebuffer_blit,
GLContext::Extensions_End
}
},
{
"standard_derivatives",
GLVersion::GL2,
@ -561,8 +575,10 @@ static const FeatureInfo sFeatureInfoArr[] = {
"sync",
GLVersion::GL3_2,
GLESVersion::ES3,
GLContext::ARB_sync,
GLContext::Extension_None,
{
GLContext::ARB_sync,
GLContext::APPLE_sync,
GLContext::Extensions_End
}
},

View File

@ -53,6 +53,15 @@ namespace gl {
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEGL
#endif
#if defined(MOZ_WIDGET_UIKIT)
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderEAGL
#include "GLContextProviderImpl.h"
#undef GL_CONTEXT_PROVIDER_NAME
#ifndef GL_CONTEXT_PROVIDER_DEFAULT
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEAGL
#endif
#endif
#ifdef MOZ_GL_PROVIDER
#define GL_CONTEXT_PROVIDER_NAME MOZ_GL_PROVIDER
#include "GLContextProviderImpl.h"

View File

@ -0,0 +1,271 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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 "GLContextProvider.h"
#include "GLContextEAGL.h"
#include "nsDebug.h"
#include "nsIWidget.h"
#include "gfxPrefs.h"
#include "gfxFailure.h"
#include "prenv.h"
#include "mozilla/Preferences.h"
#include "GeckoProfiler.h"
#import <UIKit/UIKit.h>
namespace mozilla {
namespace gl {
GLContextEAGL::GLContextEAGL(const SurfaceCaps& caps, EAGLContext* context,
GLContext* sharedContext,
bool isOffscreen, ContextProfile profile)
: GLContext(caps, sharedContext, isOffscreen)
, mContext(context)
, mBackbufferRB(0)
, mBackbufferFB(0)
, mLayer(nil)
{
SetProfileVersion(ContextProfile::OpenGLES,
[context API] == kEAGLRenderingAPIOpenGLES3 ? 300 : 200);
}
GLContextEAGL::~GLContextEAGL()
{
MakeCurrent();
if (mBackbufferFB) {
fDeleteFramebuffers(1, &mBackbufferFB);
}
if (mBackbufferRB) {
fDeleteRenderbuffers(1, &mBackbufferRB);
}
MarkDestroyed();
if (mLayer) {
mLayer = nil;
}
if (mContext) {
[EAGLContext setCurrentContext:nil];
[mContext release];
}
}
bool
GLContextEAGL::Init()
{
if (!InitWithPrefix("gl", true))
return false;
return true;
}
bool
GLContextEAGL::AttachToWindow(nsIWidget* aWidget)
{
// This should only be called once
MOZ_ASSERT(!mBackbufferFB && !mBackbufferRB);
UIView* view =
reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
if (!view) {
MOZ_CRASH("no view!");
}
mLayer = [view layer];
fGenFramebuffers(1, &mBackbufferFB);
return RecreateRB();
}
bool
GLContextEAGL::RecreateRB()
{
MakeCurrent();
CAEAGLLayer* layer = (CAEAGLLayer*)mLayer;
if (mBackbufferRB) {
// It doesn't seem to be enough to just call renderbufferStorage: below,
// we apparently have to recreate the RB.
fDeleteRenderbuffers(1, &mBackbufferRB);
mBackbufferRB = 0;
}
fGenRenderbuffers(1, &mBackbufferRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mBackbufferRB);
[mContext renderbufferStorage:LOCAL_GL_RENDERBUFFER
fromDrawable:layer];
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackbufferFB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER, mBackbufferRB);
return LOCAL_GL_FRAMEBUFFER_COMPLETE == fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
}
bool
GLContextEAGL::MakeCurrentImpl(bool aForce)
{
if (!aForce && [EAGLContext currentContext] == mContext) {
return true;
}
if (mContext) {
if(![EAGLContext setCurrentContext:mContext]) {
return false;
}
}
return true;
}
bool
GLContextEAGL::IsCurrent() {
return [EAGLContext currentContext] == mContext;
}
bool
GLContextEAGL::SetupLookupFunction()
{
return false;
}
bool
GLContextEAGL::IsDoubleBuffered() const
{
return true;
}
bool
GLContextEAGL::SupportsRobustness() const
{
return false;
}
bool
GLContextEAGL::SwapBuffers()
{
PROFILER_LABEL("GLContextEAGL", "SwapBuffers",
js::ProfileEntry::Category::GRAPHICS);
[mContext presentRenderbuffer:LOCAL_GL_RENDERBUFFER];
return true;
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
static GLContextEAGL*
GetGlobalContextEAGL()
{
return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
}
static already_AddRefed<GLContext>
CreateEAGLContext(bool aOffscreen, GLContextEAGL* sharedContext)
{
EAGLRenderingAPI apis[] = { kEAGLRenderingAPIOpenGLES3, kEAGLRenderingAPIOpenGLES2 };
// Try to create a GLES3 context if we can, otherwise fall back to GLES2
EAGLContext* context = nullptr;
for (EAGLRenderingAPI api : apis) {
if (sharedContext) {
context = [[EAGLContext alloc] initWithAPI:api
sharegroup:sharedContext->GetEAGLContext().sharegroup];
} else {
context = [[EAGLContext alloc] initWithAPI:api];
}
if (context) {
break;
}
}
if (!context) {
return nullptr;
}
SurfaceCaps caps = SurfaceCaps::ForRGBA();
ContextProfile profile = ContextProfile::OpenGLES;
RefPtr<GLContextEAGL> glContext = new GLContextEAGL(caps, context,
sharedContext,
aOffscreen,
profile);
if (!glContext->Init()) {
glContext = nullptr;
return nullptr;
}
return glContext.forget();
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget)
{
RefPtr<GLContext> glContext = CreateEAGLContext(false, GetGlobalContextEAGL());
if (!glContext) {
return nullptr;
}
if (!GLContextEAGL::Cast(glContext)->AttachToWindow(aWidget)) {
return nullptr;
}
return glContext.forget();
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateHeadless(CreateContextFlags flags)
{
return CreateEAGLContext(true, GetGlobalContextEAGL());
}
already_AddRefed<GLContext>
GLContextProviderEAGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
const SurfaceCaps& caps,
CreateContextFlags flags)
{
RefPtr<GLContext> glContext = CreateHeadless(flags);
if (!glContext->InitOffscreen(size, caps)) {
return nullptr;
}
return glContext.forget();
}
static RefPtr<GLContext> gGlobalContext;
GLContext*
GLContextProviderEAGL::GetGlobalContext()
{
if (!gGlobalContext) {
gGlobalContext = CreateEAGLContext(true, nullptr);
if (!gGlobalContext ||
!static_cast<GLContextEAGL*>(gGlobalContext.get())->Init())
{
MOZ_CRASH("Failed to create global context");
}
}
return gGlobalContext;
}
void
GLContextProviderEAGL::Shutdown()
{
gGlobalContext = nullptr;
}
} /* namespace gl */
} /* namespace mozilla */

View File

@ -686,6 +686,10 @@ struct GLContextSymbols
// get_string_indexed
typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
PFNGLGETSTRINGIPROC fGetStringi;
// APPLE_framebuffer_multisample
typedef void (GLAPIENTRY * PFNRESOLVEMULTISAMPLEFRAMEBUFFERAPPLE) (void);
PFNRESOLVEMULTISAMPLEFRAMEBUFFERAPPLE fResolveMultisampleFramebufferAPPLE;
};
} // namespace gl

View File

@ -19,7 +19,8 @@ enum class GLContextType {
WGL,
CGL,
GLX,
EGL
EGL,
EAGL
};
enum class OriginPos : uint8_t {

View File

@ -274,7 +274,7 @@ CopyDataSourceSurface(DataSourceSurface* aSource,
aDest->GetFormat() == SurfaceFormat::R8G8B8X8 ||
aDest->GetFormat() == SurfaceFormat::B8G8R8A8 ||
aDest->GetFormat() == SurfaceFormat::B8G8R8X8 ||
aDest->GetFormat() == SurfaceFormat::R5G6B5);
aDest->GetFormat() == SurfaceFormat::R5G6B5_UINT16);
const bool isSrcBGR = aSource->GetFormat() == SurfaceFormat::B8G8R8A8 ||
aSource->GetFormat() == SurfaceFormat::B8G8R8X8;
@ -288,7 +288,7 @@ CopyDataSourceSurface(DataSourceSurface* aSource,
aDest->GetFormat() == SurfaceFormat::B8G8R8A8;
const bool needsAlphaMask = !srcHasAlpha && destHasAlpha;
const bool needsConvertTo16Bits = aDest->GetFormat() == SurfaceFormat::R5G6B5;
const bool needsConvertTo16Bits = aDest->GetFormat() == SurfaceFormat::R5G6B5_UINT16;
DataSourceSurface::MappedSurface srcMap;
DataSourceSurface::MappedSurface destMap;
@ -394,7 +394,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest)
destFormat = LOCAL_GL_RGBA;
destType = LOCAL_GL_UNSIGNED_BYTE;
break;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
destFormat = LOCAL_GL_RGB;
destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV;
break;
@ -438,7 +438,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest)
case LOCAL_GL_RGB: {
MOZ_ASSERT(destPixelSize == 2);
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV);
readFormatGFX = SurfaceFormat::R5G6B5;
readFormatGFX = SurfaceFormat::R5G6B5_UINT16;
break;
}
default: {

View File

@ -82,6 +82,8 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
#elif defined(GL_PROVIDER_GLX)
if (sGLXLibrary.UseSurfaceSharing())
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, forwarder, flags);
#elif defined(MOZ_WIDGET_UIKIT)
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, forwarder, mFlags);
#else
if (gl->GetContextType() == GLContextType::EGL) {
if (XRE_IsParentProcess()) {
@ -144,7 +146,7 @@ GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
GLuint drawFB = DrawFB();
GLuint readFB = ReadFB();
if (!gl->IsSupported(GLFeature::framebuffer_blit)) {
if (!gl->IsSupported(GLFeature::split_framebuffer)) {
MOZ_ASSERT(drawFB == readFB);
gl->raw_fBindFramebuffer(target, readFB);
return;
@ -157,16 +159,10 @@ GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
break;
case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
if (!gl->IsSupported(GLFeature::framebuffer_blit))
NS_WARNING("DRAW_FRAMEBUFFER requested but unavailable.");
gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
break;
case LOCAL_GL_READ_FRAMEBUFFER_EXT:
if (!gl->IsSupported(GLFeature::framebuffer_blit))
NS_WARNING("READ_FRAMEBUFFER requested but unavailable.");
gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
break;
@ -189,7 +185,7 @@ GLScreenBuffer::BindFB(GLuint fb)
if (mInternalDrawFB == mInternalReadFB) {
mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
} else {
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
}
@ -203,7 +199,7 @@ GLScreenBuffer::BindFB(GLuint fb)
void
GLScreenBuffer::BindDrawFB(GLuint fb)
{
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
GLuint drawFB = DrawFB();
mUserDrawFB = fb;
@ -219,7 +215,7 @@ GLScreenBuffer::BindDrawFB(GLuint fb)
void
GLScreenBuffer::BindReadFB(GLuint fb)
{
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
GLuint readFB = ReadFB();
mUserReadFB = fb;
@ -248,7 +244,7 @@ GLScreenBuffer::BindFB_Internal(GLuint fb)
void
GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
{
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
mInternalDrawFB = mUserDrawFB = fb;
mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
@ -261,7 +257,7 @@ GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
void
GLScreenBuffer::BindReadFB_Internal(GLuint fb)
{
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
mInternalReadFB = mUserReadFB = fb;
mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
@ -307,7 +303,7 @@ GLScreenBuffer::GetReadFB() const
// We use raw_ here because this is debug code and we need to see what
// the driver thinks.
GLuint actual = 0;
if (mGL->IsSupported(GLFeature::framebuffer_blit))
if (mGL->IsSupported(GLFeature::split_framebuffer))
mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
else
mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
@ -422,7 +418,7 @@ GLScreenBuffer::AssureBlitted()
MOZ_ASSERT(drawFB != 0);
MOZ_ASSERT(drawFB != readFB);
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
MOZ_ASSERT(mDraw->mSize == mRead->Size());
ScopedBindFramebuffer boundFB(mGL);
@ -431,13 +427,19 @@ GLScreenBuffer::AssureBlitted()
BindReadFB_Internal(drawFB);
BindDrawFB_Internal(readFB);
const gfx::IntSize& srcSize = mDraw->mSize;
const gfx::IntSize& destSize = mRead->Size();
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
const gfx::IntSize& srcSize = mDraw->mSize;
const gfx::IntSize& destSize = mRead->Size();
mGL->raw_fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
0, 0, destSize.width, destSize.height,
LOCAL_GL_COLOR_BUFFER_BIT,
LOCAL_GL_NEAREST);
mGL->raw_fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
0, 0, destSize.width, destSize.height,
LOCAL_GL_COLOR_BUFFER_BIT,
LOCAL_GL_NEAREST);
} else if (mGL->IsExtensionSupported(GLContext::APPLE_framebuffer_multisample)) {
mGL->fResolveMultisampleFramebufferAPPLE();
} else {
MOZ_CRASH("No available blit methods.");
}
// Done!
}

View File

@ -486,10 +486,10 @@ UploadImageDataToTexture(GLContext* gl,
}
internalFormat = LOCAL_GL_RGBA;
break;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
internalFormat = format = LOCAL_GL_RGB;
type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
surfaceFormat = SurfaceFormat::R5G6B5;
surfaceFormat = SurfaceFormat::R5G6B5_UINT16;
break;
case SurfaceFormat::A8:
internalFormat = format = LOCAL_GL_LUMINANCE;

View File

@ -62,7 +62,7 @@ ScopedGLState::UnwrapImpl()
void
ScopedBindFramebuffer::Init()
{
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
if (mGL->IsSupported(GLFeature::split_framebuffer)) {
mOldReadFB = mGL->GetReadFB();
mOldDrawFB = mGL->GetDrawFB();
} else {

View File

@ -95,6 +95,7 @@ SharedSurface_Basic::~SharedSurface_Basic()
mGL->fDeleteTextures(1, &mTex);
}
////////////////////////////////////////////////////////////////////////
SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
@ -102,6 +103,88 @@ SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& cap
: SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
{ }
////////////////////////////////////////////////////////////////////////
// SharedSurface_GLTexture
/*static*/ UniquePtr<SharedSurface_GLTexture>
SharedSurface_GLTexture::Create(GLContext* prodGL,
const GLFormats& formats,
const IntSize& size,
bool hasAlpha)
{
MOZ_ASSERT(prodGL);
prodGL->MakeCurrent();
UniquePtr<SharedSurface_GLTexture> ret;
GLContext::LocalErrorScope localError(*prodGL);
GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
GLenum err = localError.GetError();
MOZ_ASSERT_IF(err, err == LOCAL_GL_OUT_OF_MEMORY);
if (err) {
prodGL->fDeleteTextures(1, &tex);
return Move(ret);
}
ret.reset(new SharedSurface_GLTexture(prodGL, size,
hasAlpha, tex));
return Move(ret);
}
SharedSurface_GLTexture::~SharedSurface_GLTexture()
{
if (!mGL->MakeCurrent())
return;
if (mTex) {
mGL->fDeleteTextures(1, &mTex);
}
if (mSync) {
mGL->fDeleteSync(mSync);
}
}
void
SharedSurface_GLTexture::ProducerReleaseImpl()
{
mGL->MakeCurrent();
if (mGL->IsSupported(GLFeature::sync)) {
if (mSync) {
mGL->fDeleteSync(mSync);
mSync = 0;
}
mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
if (mSync) {
mGL->fFlush();
return;
}
}
MOZ_ASSERT(!mSync);
mGL->fFinish();
}
bool
SharedSurface_GLTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{
*out_descriptor = layers::SurfaceDescriptorSharedGLTexture(ProdTexture(),
ProdTextureTarget(),
(uintptr_t)mSync,
mSize,
mHasAlpha);
// Transfer ownership of the fence to the host
mSync = nullptr;
return true;
}
} // namespace gl
} /* namespace mozilla */

View File

@ -93,6 +93,78 @@ public:
}
};
// Using shared GL textures:
class SharedSurface_GLTexture
: public SharedSurface
{
public:
static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha);
static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
MOZ_ASSERT(surf->mType == SharedSurfaceType::SharedGLTexture);
return (SharedSurface_GLTexture*)surf;
}
protected:
const GLuint mTex;
GLsync mSync;
SharedSurface_GLTexture(GLContext* prodGL,
const gfx::IntSize& size,
bool hasAlpha,
GLuint tex)
: SharedSurface(SharedSurfaceType::SharedGLTexture,
AttachmentType::GLTexture,
prodGL,
size,
hasAlpha, true)
, mTex(tex)
, mSync(0)
{
}
public:
virtual ~SharedSurface_GLTexture();
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void Fence() override {}
virtual bool WaitSync() override { MOZ_CRASH("should not be called"); }
virtual bool PollSync() override { MOZ_CRASH("should not be called"); }
virtual GLuint ProdTexture() override {
return mTex;
}
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
};
class SurfaceFactory_GLTexture
: public SurfaceFactory
{
public:
SurfaceFactory_GLTexture(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::SharedGLTexture, prodGL, caps, allocator, flags)
{
}
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;
return SharedSurface_GLTexture::Create(mGL, mFormats, size, hasAlpha);
}
};
} // namespace gl
} /* namespace mozilla */

View File

@ -77,6 +77,7 @@ enum class SharedSurfaceType : uint8_t {
Gralloc,
IOSurface,
GLXDrawable,
SharedGLTexture,
Max
};

View File

@ -20,7 +20,7 @@ GLFormatForImage(gfx::SurfaceFormat aFormat)
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
return LOCAL_GL_RGBA;
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R5G6B5_UINT16:
return LOCAL_GL_RGB;
case gfx::SurfaceFormat::A8:
return LOCAL_GL_LUMINANCE;
@ -38,7 +38,7 @@ GLTypeForImage(gfx::SurfaceFormat aFormat)
case gfx::SurfaceFormat::B8G8R8X8:
case gfx::SurfaceFormat::A8:
return LOCAL_GL_UNSIGNED_BYTE;
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R5G6B5_UINT16:
return LOCAL_GL_UNSIGNED_SHORT_5_6_5;
default:
NS_WARNING("Unknown GL format for Surface format");
@ -69,7 +69,7 @@ TextureImageEGL::TextureImageEGL(GLuint aTexture,
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(GetContentType());
}
if (mUpdateFormat == gfx::SurfaceFormat::R5G6B5) {
if (mUpdateFormat == gfx::SurfaceFormat::R5G6B5_UINT16) {
mTextureFormat = gfx::SurfaceFormat::R8G8B8X8;
} else if (mUpdateFormat == gfx::SurfaceFormat::B8G8R8X8) {
mTextureFormat = gfx::SurfaceFormat::B8G8R8X8;

View File

@ -10,6 +10,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
gl_provider = 'WGL'
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
gl_provider = 'CGL'
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'uikit':
gl_provider = 'EAGL'
elif CONFIG['MOZ_WIDGET_GTK']:
if CONFIG['MOZ_EGL_XRENDER_COMPOSITE']:
gl_provider = 'EGL'
@ -103,6 +105,15 @@ if gl_provider == 'CGL':
SOURCES += [
'SharedSurfaceIO.cpp',
]
elif gl_provider == 'EAGL':
# These files include ObjC headers that are unfriendly to unified builds
SOURCES += [
'GLContextProviderEAGL.mm',
]
EXPORTS += [
'GLContextEAGL.h',
]
elif gl_provider == 'GLX':
# GLContextProviderGLX.cpp needs to be kept out of UNIFIED_SOURCES
# as it includes X11 headers which cause conflicts.

View File

@ -267,7 +267,7 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat,
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
case gfx::SurfaceFormat::R8G8B8X8:
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R5G6B5_UINT16:
case gfx::SurfaceFormat::R8G8B8A8:
result = new EffectRGB(aSource, isAlphaPremultiplied, aFilter);
break;

View File

@ -384,7 +384,7 @@ ConvertOmxYUVFormatToRGB565(android::sp<GraphicBuffer>& aBuffer,
return BAD_VALUE;
}
uint32_t pixelStride = aMappedSurface->mStride/gfx::BytesPerPixel(gfx::SurfaceFormat::R5G6B5);
uint32_t pixelStride = aMappedSurface->mStride/gfx::BytesPerPixel(gfx::SurfaceFormat::R5G6B5_UINT16);
rv = colorConverter.convert(buffer, width, height,
0, 0, width - 1, height - 1 /* source crop */,
aMappedSurface->mData, pixelStride, height,
@ -405,7 +405,7 @@ GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
MOZ_ASSERT(aGraphicBuffer.get());
RefPtr<gfx::DataSourceSurface> surface =
gfx::Factory::CreateDataSourceSurface(aSize, gfx::SurfaceFormat::R5G6B5);
gfx::Factory::CreateDataSourceSurface(aSize, gfx::SurfaceFormat::R5G6B5_UINT16);
if (NS_WARN_IF(!surface)) {
return nullptr;
}

View File

@ -316,7 +316,8 @@ AppendToString(std::stringstream& aStream, mozilla::gfx::SurfaceFormat format,
case SurfaceFormat::B8G8R8X8: aStream << "SurfaceFormat::B8G8R8X8"; break;
case SurfaceFormat::R8G8B8A8: aStream << "SurfaceFormat::R8G8B8A8"; break;
case SurfaceFormat::R8G8B8X8: aStream << "SurfaceFormat::R8G8B8X8"; break;
case SurfaceFormat::R5G6B5: aStream << "SurfaceFormat::R5G6B5"; break;
case SurfaceFormat::R5G6B5_UINT16:
aStream << "SurfaceFormat::R5G6B5_UINT16"; break;
case SurfaceFormat::A8: aStream << "SurfaceFormat::A8"; break;
case SurfaceFormat::YUV: aStream << "SurfaceFormat::YUV"; break;
case SurfaceFormat::NV12: aStream << "SurfaceFormat::NV12"; break;

View File

@ -190,6 +190,9 @@ APZCTreeManager::UpdateHitTestingTree(CompositorParent* aCompositor,
mApzcTreeLog << "[end]\n";
}
// We do not support tree structures where the root node has siblings.
MOZ_ASSERT(!(mRootNode && mRootNode->GetPrevSibling()));
for (size_t i = 0; i < state.mNodesToDestroy.Length(); i++) {
APZCTM_LOG("Destroying node at %p with APZC %p\n",
state.mNodesToDestroy[i].get(),

View File

@ -21,10 +21,18 @@ enum HitTestResult {
};
enum CancelAnimationFlags : uint32_t {
Default = 0, /* Cancel all animations */
ExcludeOverscroll = 1 /* Don't clear overscroll */
Default = 0x0, /* Cancel all animations */
ExcludeOverscroll = 0x1, /* Don't clear overscroll */
RequestSnap = 0x2 /* Request snapping to snap points */
};
inline CancelAnimationFlags
operator|(CancelAnimationFlags a, CancelAnimationFlags b)
{
return static_cast<CancelAnimationFlags>(static_cast<int>(a)
| static_cast<int>(b));
}
enum class ScrollSource {
// scrollTo() or something similar.
DOM,

View File

@ -663,7 +663,14 @@ public:
bool continueX = mApzc.mX.SampleOverscrollAnimation(aDelta);
bool continueY = mApzc.mY.SampleOverscrollAnimation(aDelta);
if (!continueX && !continueY) {
mApzc.OverscrollAnimationEnding();
// If we got into overscroll from a fling, that fling did not request a
// fling snap to avoid a resulting scrollTo from cancelling the overscroll
// animation too early. We do still want to request a fling snap, though,
// in case the end of the axis at which we're overscrolled is not a valid
// snap point, so we request one now. If there are no snap points, this will
// do nothing. If there are snap points, we'll get a scrollTo that snaps us
// back to the nearest valid snap point.
mApzc.RequestSnap();
return false;
}
return true;
@ -882,7 +889,7 @@ AsyncPanZoomController::Destroy()
{
APZThreadUtils::AssertOnCompositorThread();
CancelAnimation();
CancelAnimation(CancelAnimationFlags::RequestSnap);
{ // scope the lock
MonitorAutoLock lock(mRefPtrMonitor);
@ -1504,6 +1511,10 @@ nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent
} else {
ClearOverscroll();
}
// Along with clearing the overscroll, we also want to snap to the nearest
// snap point as appropriate, so ask the main thread (which knows about such
// things) to handle it.
RequestSnap();
ScheduleComposite();
RequestContentRepaint();
@ -2490,6 +2501,11 @@ void AsyncPanZoomController::CancelAnimation(CancelAnimationFlags aFlags) {
ClearOverscroll();
repaint = true;
}
// Similar to relieving overscroll, we also need to snap to any snap points
// if appropriate, so ask the main thread to do that.
if (aFlags & CancelAnimationFlags::RequestSnap) {
RequestSnap();
}
if (repaint) {
RequestContentRepaint();
ScheduleComposite();
@ -2670,6 +2686,9 @@ bool AsyncPanZoomController::SnapBackIfOverscrolled() {
StartOverscrollAnimation(ParentLayerPoint(0, 0));
return true;
}
// If we don't kick off an overscroll animation, we still need to ask the
// main thread to snap to any nearby snap points.
RequestSnap();
return false;
}
@ -3345,7 +3364,7 @@ AsyncPanZoomController::CancelAnimationAndGestureState()
{
mX.CancelGesture();
mY.CancelGesture();
CancelAnimation();
CancelAnimation(CancelAnimationFlags::RequestSnap);
}
bool
@ -3531,14 +3550,7 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
}
}
void AsyncPanZoomController::OverscrollAnimationEnding() {
// If we got into overscroll from a fling, that fling did not request a
// fling snap to avoid a resulting scrollTo from cancelling the overscroll
// animation too early. We do still want to request a fling snap, though,
// in case the end of the axis at which we're overscrolled is not a valid
// snap point, so we request one now. If there are no snap points, this will
// do nothing. If there are snap points, we'll get a scrollTo that snaps us
// back to the nearest valid snap point.
void AsyncPanZoomController::RequestSnap() {
if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
controller->RequestFlingSnap(mFrameMetrics.GetScrollId(),
mFrameMetrics.GetScrollOffset());

View File

@ -647,9 +647,10 @@ protected:
// Common processing at the end of a touch block.
void OnTouchEndOrCancel();
// This is called by OverscrollAnimation to notify us when the overscroll
// animation is ending.
void OverscrollAnimationEnding();
// This is called to request that the main thread snap the scroll position
// to a nearby snap position if appropriate. The current scroll position is
// used as the final destination.
void RequestSnap();
uint64_t mLayersId;
RefPtr<CompositorParent> mCompositorParent;

View File

@ -26,7 +26,7 @@ HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
case android::PIXEL_FORMAT_RGBX_8888:
return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8;
case android::PIXEL_FORMAT_RGB_565:
return gfx::SurfaceFormat::R5G6B5;
return gfx::SurfaceFormat::R5G6B5_UINT16;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
@ -37,12 +37,12 @@ HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
#endif
// Needs convert to RGB565
return gfx::SurfaceFormat::R5G6B5;
return gfx::SurfaceFormat::R5G6B5_UINT16;
default:
if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) {
// Reserved range for HAL specific formats.
// Needs convert to RGB565
return gfx::SurfaceFormat::R5G6B5;
return gfx::SurfaceFormat::R5G6B5_UINT16;
} else {
MOZ_CRASH("Unhandled HAL pixel format");
return SurfaceFormat::UNKNOWN; // not reached

View File

@ -215,7 +215,7 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
//
// Desktop does not support async zoom yet, so we ignore this for those
// platforms.
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_UIKIT)
if (mWidget && mWidget->GetOwningTabChild()) {
mCompositorMightResample = AsyncPanZoomEnabled();
}

View File

@ -215,6 +215,7 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:

View File

@ -82,6 +82,14 @@ struct EGLImageDescriptor {
bool hasAlpha;
};
struct SurfaceDescriptorSharedGLTexture {
uint32_t texture;
uint32_t target;
uintptr_t fence;
IntSize size;
bool hasAlpha;
};
struct NewSurfaceDescriptorGralloc {
MaybeMagicGrallocBufferHandle buffer;
bool isOpaque;
@ -116,6 +124,7 @@ union SurfaceDescriptor {
EGLImageDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
SurfaceDescriptorSharedGLTexture;
null_t;
};

View File

@ -833,7 +833,7 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect,
MOZ_ASSERT_IF(source->GetTextureTarget() == LOCAL_GL_TEXTURE_RECTANGLE_ARB,
source->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
source->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
source->GetFormat() == gfx::SurfaceFormat::R5G6B5);
source->GetFormat() == gfx::SurfaceFormat::R5G6B5_UINT16);
config = ShaderConfigFromTargetAndFormat(source->GetTextureTarget(),
source->GetFormat());
break;
@ -1532,7 +1532,7 @@ CompositorOGL::Pause()
bool
CompositorOGL::Resume()
{
#ifdef MOZ_WIDGET_ANDROID
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_UIKIT)
if (!gl() || gl()->IsDestroyed())
return false;

View File

@ -181,7 +181,7 @@ SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
case PIXEL_FORMAT_RGBX_8888:
return gfx::SurfaceFormat::R8G8B8X8;
case PIXEL_FORMAT_RGB_565:
return gfx::SurfaceFormat::R5G6B5;
return gfx::SurfaceFormat::R5G6B5_UINT16;
case HAL_PIXEL_FORMAT_YV12:
return gfx::SurfaceFormat::YUV;
default:
@ -284,7 +284,7 @@ GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
format = android::PIXEL_FORMAT_RGBX_8888;
mFlags |= TextureFlags::RB_SWAPPED;
break;
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R5G6B5_UINT16:
format = android::PIXEL_FORMAT_RGB_565;
break;
case gfx::SurfaceFormat::YUV:
@ -329,7 +329,7 @@ GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
// there is no android BGRX format?
format = android::PIXEL_FORMAT_RGBX_8888;
break;
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R5G6B5_UINT16:
format = android::PIXEL_FORMAT_RGB_565;
break;
default:

View File

@ -35,7 +35,7 @@ SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
case android::PIXEL_FORMAT_RGBX_8888:
return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8;
case android::PIXEL_FORMAT_RGB_565:
return gfx::SurfaceFormat::R5G6B5;
return gfx::SurfaceFormat::R5G6B5_UINT16;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:

View File

@ -249,7 +249,7 @@ ShaderConfigFromTargetAndFormat(GLenum aTarget,
aFormat == gfx::SurfaceFormat::B8G8R8X8);
config.SetNoAlpha(aFormat == gfx::SurfaceFormat::B8G8R8X8 ||
aFormat == gfx::SurfaceFormat::R8G8B8X8 ||
aFormat == gfx::SurfaceFormat::R5G6B5);
aFormat == gfx::SurfaceFormat::R5G6B5_UINT16);
return config;
}

View File

@ -104,6 +104,16 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
break;
}
#endif
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
result = new GLTextureHost(aFlags, desc.texture(),
desc.target(),
(GLsync)desc.fence(),
desc.size(),
desc.hasAlpha());
break;
}
default: return nullptr;
}
return result.forget();
@ -645,5 +655,76 @@ EGLImageTextureHost::GetFormat() const
return mTextureSource->GetFormat();
}
//
GLTextureHost::GLTextureHost(TextureFlags aFlags,
GLuint aTextureHandle,
GLenum aTarget,
GLsync aSync,
gfx::IntSize aSize,
bool aHasAlpha)
: TextureHost(aFlags)
, mTexture(aTextureHandle)
, mTarget(aTarget)
, mSync(aSync)
, mSize(aSize)
, mHasAlpha(aHasAlpha)
, mCompositor(nullptr)
{}
GLTextureHost::~GLTextureHost()
{}
gl::GLContext*
GLTextureHost::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
bool
GLTextureHost::Lock()
{
if (!mCompositor) {
return false;
}
if (mSync) {
gl()->MakeCurrent();
gl()->fWaitSync(mSync, 0, LOCAL_GL_TIMEOUT_IGNORED);
gl()->fDeleteSync(mSync);
mSync = 0;
}
if (!mTextureSource) {
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8;
mTextureSource = new GLTextureSource(mCompositor,
mTexture,
mTarget,
mSize,
format,
false /* owned by the client */);
}
return true;
}
void
GLTextureHost::SetCompositor(Compositor* aCompositor)
{
MOZ_ASSERT(aCompositor);
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
mCompositor = glCompositor;
if (mTextureSource) {
mTextureSource->SetCompositor(glCompositor);
}
}
gfx::SurfaceFormat
GLTextureHost::GetFormat() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetFormat();
}
} // namespace layers
} // namespace mozilla

View File

@ -279,6 +279,56 @@ protected:
bool mExternallyOwned;
};
class GLTextureHost : public TextureHost
{
public:
GLTextureHost(TextureFlags aFlags,
GLuint aTextureHandle,
GLenum aTarget,
GLsync aSync,
gfx::IntSize aSize,
bool aHasAlpha);
virtual ~GLTextureHost();
// We don't own anything.
virtual void DeallocateDeviceData() override {}
virtual void SetCompositor(Compositor* aCompositor) override;
virtual bool Lock() override;
virtual void Unlock() override {}
virtual gfx::SurfaceFormat GetFormat() const override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
{
aTexture = mTextureSource;
return !!aTexture;
}
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
{
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
gl::GLContext* gl() const;
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual const char* Name() override { return "GLTextureHost"; }
protected:
const GLuint mTexture;
const GLenum mTarget;
GLsync mSync;
const gfx::IntSize mSize;
const bool mHasAlpha;
RefPtr<CompositorOGL> mCompositor;
RefPtr<GLTextureSource> mTextureSource;
};
////////////////////////////////////////////////////////////////////////
// SurfaceTexture

View File

@ -88,7 +88,7 @@ inline gfxImageFormat SurfaceFormatToImageFormat(SurfaceFormat aFormat)
return gfxImageFormat::ARGB32;
case SurfaceFormat::B8G8R8X8:
return gfxImageFormat::RGB24;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
return gfxImageFormat::RGB16_565;
case SurfaceFormat::A8:
return gfxImageFormat::A8;
@ -105,7 +105,7 @@ inline SurfaceFormat ImageFormatToSurfaceFormat(gfxImageFormat aFormat)
case gfxImageFormat::RGB24:
return SurfaceFormat::B8G8R8X8;
case gfxImageFormat::RGB16_565:
return SurfaceFormat::R5G6B5;
return SurfaceFormat::R5G6B5_UINT16;
case gfxImageFormat::A8:
return SurfaceFormat::A8;
default:
@ -117,7 +117,7 @@ inline SurfaceFormat ImageFormatToSurfaceFormat(gfxImageFormat aFormat)
inline gfxContentType ContentForFormat(const SurfaceFormat &aFormat)
{
switch (aFormat) {
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
case SurfaceFormat::B8G8R8X8:
case SurfaceFormat::R8G8B8X8:
return gfxContentType::COLOR;

View File

@ -1852,7 +1852,7 @@ gfxPlatform::Optimal2DFormatForContent(gfxContentType aContent)
case gfxImageFormat::RGB24:
return mozilla::gfx::SurfaceFormat::B8G8R8X8;
case gfxImageFormat::RGB16_565:
return mozilla::gfx::SurfaceFormat::R5G6B5;
return mozilla::gfx::SurfaceFormat::R5G6B5_UINT16;
default:
NS_NOTREACHED("unknown gfxImageFormat for gfxContentType::COLOR");
return mozilla::gfx::SurfaceFormat::B8G8R8A8;

Some files were not shown because too many files have changed in this diff Show More