Merge m-c to fx-team. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-12-16 16:08:15 -05:00
commit 4cfa23a95a
78 changed files with 686 additions and 153 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -129,7 +129,7 @@
<!-- Stock Android things -->
<project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
<!-- dolphin specific things -->
<project name="device/sprd" path="device/sprd" revision="3a0f1b51e3b27b36b9df484f3c286b6099889f6e"/>
<project name="device/sprd" path="device/sprd" revision="ea8680ba32e41e5f7a2ff12d692f2a159cb19501"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="4387fe988e5a1001f29ce05fcfda03ed2d32137b"/>
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "7d6f0979c4f3f3c5702033739561ba8d4159b409",
"revision": "99bea97a4bd9d6af1d7462e1abe15c8aaf4d7981",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -334,7 +334,11 @@ fi
# Even after dropping 10.6 support, MOZ_PIE would not be useful since it's the
# default (and clang says the -pie option is not used).
# On other Unix systems, some file managers (Nautilus) can't start PIE programs
MOZ_PIE=
if test -n "$gonkdir" -a "$ANDROID_VERSION" -ge 16; then
MOZ_PIE=1
else
MOZ_PIE=
fi
MOZ_ARG_ENABLE_BOOL(pie,
[ --enable-pie Enable Position Independent Executables],

View File

@ -238,7 +238,7 @@ nsGonkCameraControl::Initialize()
while (i > 0) {
--i;
if (modes[i].EqualsASCII(kCenterWeighted)) {
mParams.Set(CAMERA_PARAM_METERINGMODE, kCenterWeighted);
mParams.Set(CAMERA_PARAM_METERINGMODE, modes[i]);
PushParametersImpl();
break;
}

View File

@ -3420,7 +3420,7 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
const gfxTextRun::DetailedGlyph *d = mTextRun->GetDetailedGlyphs(i);
if (glyphs[i].IsMissing()) {
if (glyphs[i].IsMissing() && d->mAdvance > 0) {
newGlyph.mIndex = 0;
if (rtl) {
inlinePos = baselineOriginInline - advanceSum -

View File

@ -160,11 +160,21 @@ public:
if (aKeyRange->IsOnly()) {
Assign(LoggingString(aKeyRange->Lower()));
} else {
Assign(aKeyRange->LowerOpen() ? kOpenParen : kOpenBracket);
if (aKeyRange->LowerOpen()) {
Assign(kOpenParen);
} else {
Assign(kOpenBracket);
}
Append(LoggingString(aKeyRange->Lower()));
AppendLiteral(", ");
Append(LoggingString(aKeyRange->Upper()));
Append(aKeyRange->UpperOpen() ? kCloseParen : kCloseBracket);
if (aKeyRange->UpperOpen()) {
Append(kCloseParen);
} else {
Append(kCloseBracket);
}
}
} else {
AssignLiteral("<undefined>");

View File

@ -2734,6 +2734,12 @@ MediaDecoderStateMachine::FlushDecoding()
DecodeTaskQueue()->FlushAndDispatch(task);
}
// These flags will be reset when the decoded data returned in OnAudioDecoded()
// and OnVideoDecoded(). Because the decode tasks are flushed, these flags need
// to be reset here.
mAudioRequestPending = false;
mVideoRequestPending = false;
// We must reset playback so that all references to frames queued
// in the state machine are dropped, else subsequent calls to Shutdown()
// or ReleaseMediaResources() can fail on B2G.

View File

@ -193,7 +193,6 @@ IsAndroidAvailable()
nsString vendor;
if (NS_FAILED(gfxInfo->GetAdapterVendorID(vendor)) ||
vendor.Find("Imagination") == 0) {
printf_stderr("SNORP: not doing video for PowerVR\n");
return nullptr;
}

View File

@ -204,6 +204,14 @@ private:
};
#endif
void MP4Reader::RequestCodecResource() {
#ifdef MOZ_GONK_MEDIACODEC
if(mVideo.mDecoder) {
mVideo.mDecoder->AllocateMediaResources();
}
#endif
}
bool MP4Reader::IsWaitingOnCodecResource() {
#ifdef MOZ_GONK_MEDIACODEC
return mVideo.mDecoder && mVideo.mDecoder->IsWaitingMediaResources();
@ -273,6 +281,14 @@ MP4Reader::IsSupportedVideoMimeType(const char* aMimeType)
mPlatform->SupportsVideoMimeType(aMimeType);
}
void
MP4Reader::PreReadMetadata()
{
if (mPlatform) {
RequestCodecResource();
}
}
nsresult
MP4Reader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
@ -729,6 +745,7 @@ MP4Reader::Flush(TrackType aTrack)
data.RejectPromise(CANCELED, __func__);
}
data.mDiscontinuity = true;
data.mUpdateScheduled = false;
}
if (aTrack == kVideo) {
mQueuedVideoSample = nullptr;

View File

@ -45,6 +45,11 @@ public:
virtual bool HasAudio() MOZ_OVERRIDE;
virtual bool HasVideo() MOZ_OVERRIDE;
// PreReadMetadata() is called by MediaDecoderStateMachine::DecodeMetadata()
// before checking hardware resource. In Gonk, it requests hardware codec so
// MediaDecoderStateMachine could go to DORMANT state if the hardware codec is
// not available.
virtual void PreReadMetadata() MOZ_OVERRIDE;
virtual nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) MOZ_OVERRIDE;
@ -107,6 +112,7 @@ private:
bool IsSupportedAudioMimeType(const char* aMimeType);
bool IsSupportedVideoMimeType(const char* aMimeType);
void NotifyResourcesStatusChanged();
void RequestCodecResource();
bool IsWaitingOnCodecResource();
virtual bool IsWaitingOnCDMResource() MOZ_OVERRIDE;

View File

@ -231,6 +231,7 @@ public:
virtual bool IsDormantNeeded() {
return false;
};
virtual void AllocateMediaResources() {}
virtual void ReleaseMediaResources() {}
virtual void ReleaseDecoder() {}
};

View File

@ -164,6 +164,12 @@ GonkMediaDataDecoder::IsDormantNeeded() {
return mDecoder.get() ? true : false;
}
void
GonkMediaDataDecoder::AllocateMediaResources()
{
mManager->AllocateMediaResources();
}
void
GonkMediaDataDecoder::ReleaseMediaResources() {
mManager->ReleaseMediaResources();

View File

@ -35,6 +35,8 @@ public:
nsRefPtr<MediaData>& aOutput) = 0;
virtual nsresult Flush() = 0;
virtual void AllocateMediaResources() {};
virtual void ReleaseMediaResources() {};
};
@ -65,6 +67,8 @@ public:
virtual bool IsDormantNeeded() MOZ_OVERRIDE;
virtual void AllocateMediaResources() MOZ_OVERRIDE;
virtual void ReleaseMediaResources() MOZ_OVERRIDE;
private:

View File

@ -474,6 +474,12 @@ GonkVideoDecoderManager::Flush()
return NS_OK;
}
void
GonkVideoDecoderManager::AllocateMediaResources()
{
mDecoder->RequestMediaResources();
}
void
GonkVideoDecoderManager::codecReserved()
{

View File

@ -52,6 +52,8 @@ public:
virtual nsresult Flush() MOZ_OVERRIDE;
virtual void AllocateMediaResources();
virtual void ReleaseMediaResources();
static void RecycleCallback(TextureClient* aClient, void* aClosure);

View File

@ -135,6 +135,12 @@ MediaCodecProxy::requestResource()
return true;
}
void
MediaCodecProxy::RequestMediaResources()
{
requestResource();
}
void
MediaCodecProxy::cancelResource()
{
@ -572,7 +578,6 @@ status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
status_t err = dequeueOutputBuffer(&index, &offset, &size,
&timeUs, &flags, aTimeoutUs);
if (err != OK) {
ALOG("Output returned %d", err);
return err;
}
@ -598,9 +603,10 @@ status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
bool MediaCodecProxy::IsWaitingResources()
{
// Write Lock for mCodec
RWLock::AutoWLock awl(mCodecLock);
return mCodec == nullptr;
if (mResourceHandler.get()) {
return mResourceHandler->IsWaitingResource();
}
return false;
}
bool MediaCodecProxy::IsDormantNeeded()

View File

@ -131,6 +131,7 @@ public:
bool Prepare();
bool IsWaitingResources();
bool IsDormantNeeded();
void RequestMediaResources();
void ReleaseMediaResources();
// This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event.
bool UpdateOutputBuffers();

View File

@ -5,15 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaResourceHandler.h"
#include "mozilla/NullPtr.h"
namespace android {
MediaResourceHandler::MediaResourceHandler(const wp<ResourceListener> &aListener)
: mListener(aListener)
, mState(MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE)
, mType(IMediaResourceManagerService::INVALID_RESOURCE_TYPE)
, mWaitingResource(false)
{
}
@ -22,6 +21,13 @@ MediaResourceHandler::~MediaResourceHandler()
cancelResource();
}
bool
MediaResourceHandler::IsWaitingResource()
{
Mutex::Autolock al(mLock);
return mWaitingResource;
}
bool
MediaResourceHandler::requestResource(IMediaResourceManagerService::ResourceType aType)
{
@ -45,6 +51,7 @@ MediaResourceHandler::requestResource(IMediaResourceManagerService::ResourceType
mClient = client;
mService = service;
mType = aType;
mWaitingResource = true;
return true;
}
@ -58,6 +65,7 @@ MediaResourceHandler::cancelResource()
mService->cancelClient(mClient, (int)mType);
}
mWaitingResource = false;
mClient = nullptr;
mService = nullptr;
}
@ -70,19 +78,15 @@ MediaResourceHandler::statusChanged(int aEvent)
Mutex::Autolock autoLock(mLock);
MediaResourceManagerClient::State state = (MediaResourceManagerClient::State)aEvent;
if (state == mState) {
return;
}
mState = state;
listener = mListener.promote();
if (listener == nullptr) {
return;
}
if (mState == MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
mWaitingResource = false;
MediaResourceManagerClient::State state = (MediaResourceManagerClient::State)aEvent;
if (state == MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
listener->resourceReserved();
} else {
listener->resourceCanceled();

View File

@ -42,6 +42,8 @@ public:
// Cancel Resource
void cancelResource();
bool IsWaitingResource();
protected:
// MediaResourceManagerClient::EventListener::statusChanged()
virtual void statusChanged(int event);
@ -57,10 +59,11 @@ private:
// Resource Management
Mutex mLock;
MediaResourceManagerClient::State mState;
sp<IMediaResourceManagerClient> mClient;
sp<IMediaResourceManagerService> mService;
IMediaResourceManagerService::ResourceType mType;
bool mWaitingResource;
};
} // namespace android

View File

@ -8,6 +8,8 @@
#include <utils/Log.h>
#include "GrallocImages.h"
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "VideoUtils.h"
#include "ScreenOrientation.h"
@ -28,6 +30,8 @@ extern PRLogModuleInfo* GetMediaManagerLog();
#define LOGFRAME(msg)
#endif
#define WEBRTC_GONK_VIDEO_SOURCE_POOL_BUFFERS 10
// We are subclassed from CameraControlListener, which implements a
// threadsafe reference-count for us.
NS_IMPL_QUERY_INTERFACE(MediaEngineGonkVideoSource, nsISupports)
@ -254,6 +258,9 @@ MediaEngineGonkVideoSource::AllocImpl() {
// to explicitly remove this--destroying the CameraControl object
// in DeallocImpl() will do that for us.
mCameraControl->AddListener(this);
mTextureClientAllocator =
new layers::TextureClientRecycleAllocator(layers::ImageBridgeChild::GetSingleton());
mTextureClientAllocator->SetMaxPoolSize(WEBRTC_GONK_VIDEO_SOURCE_POOL_BUFFERS);
}
mCallbackMonitor.Notify();
}
@ -263,6 +270,7 @@ MediaEngineGonkVideoSource::DeallocImpl() {
MOZ_ASSERT(NS_IsMainThread());
mCameraControl = nullptr;
mTextureClientAllocator = nullptr;
}
// The same algorithm from bug 840244
@ -578,14 +586,16 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(aImage);
android::sp<android::GraphicBuffer> graphicBuffer = nativeImage->GetGraphicBuffer();
void *pMem = nullptr;
// Bug 1109957 size will be wrong if width or height are odd
uint32_t size = aWidth * aHeight * 3 / 2;
MOZ_ASSERT(!(aWidth & 1) && !(aHeight & 1));
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_MASK, &pMem);
uint8_t* srcPtr = static_cast<uint8_t*>(pMem);
// Create a video frame and append it to the track.
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(ImageFormat::PLANAR_YCBCR);
layers::PlanarYCbCrImage* videoImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
ImageFormat format = ImageFormat::GRALLOC_PLANAR_YCBCR;
nsRefPtr<layers::Image> image = mImageContainer->CreateImage(format);
uint32_t dstWidth;
uint32_t dstHeight;
@ -599,35 +609,48 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
}
uint32_t half_width = dstWidth / 2;
uint8_t* dstPtr = videoImage->AllocateAndGetNewBuffer(size);
layers::GrallocImage* videoImage = static_cast<layers::GrallocImage*>(image.get());
MOZ_ASSERT(mTextureClientAllocator);
RefPtr<layers::TextureClient> textureClient
= mTextureClientAllocator->CreateOrRecycleForDrawing(gfx::SurfaceFormat::YUV,
gfx::IntSize(dstWidth, dstHeight),
gfx::BackendType::NONE,
layers::TextureFlags::DEFAULT,
layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
if (!textureClient) {
return;
}
RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient =
static_cast<layers::GrallocTextureClientOGL*>(textureClient.get());
android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
void* destMem = nullptr;
destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
uint8_t* dstPtr = static_cast<uint8_t*>(destMem);
int32_t yStride = destBuffer->getStride();
// Align to 16 bytes boundary
int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;
libyuv::ConvertToI420(srcPtr, size,
dstPtr, dstWidth,
dstPtr + (dstWidth * dstHeight), half_width,
dstPtr + (dstWidth * dstHeight * 5 / 4), half_width,
dstPtr, yStride,
dstPtr + (yStride * dstHeight + (uvStride * dstHeight / 2)), uvStride,
dstPtr + (yStride * dstHeight), uvStride,
0, 0,
aWidth, aHeight,
aWidth, aHeight,
static_cast<libyuv::RotationMode>(mRotation),
ConvertPixelFormatToFOURCC(graphicBuffer->getPixelFormat()));
libyuv::FOURCC_NV21);
destBuffer->unlock();
graphicBuffer->unlock();
const uint8_t lumaBpp = 8;
const uint8_t chromaBpp = 4;
layers::GrallocImage::GrallocData data;
layers::PlanarYCbCrData data;
data.mYChannel = dstPtr;
data.mYSize = IntSize(dstWidth, dstHeight);
data.mYStride = dstWidth * lumaBpp / 8;
data.mCbCrStride = dstWidth * chromaBpp / 8;
data.mCbChannel = dstPtr + dstHeight * data.mYStride;
data.mCrChannel = data.mCbChannel +( dstHeight * data.mCbCrStride / 2);
data.mCbCrSize = IntSize(dstWidth / 2, dstHeight / 2);
data.mPicX = 0;
data.mPicY = 0;
data.mPicSize = IntSize(dstWidth, dstHeight);
data.mStereoMode = StereoMode::MONO;
videoImage->SetDataNoCopy(data);
data.mPicSize = gfx::IntSize(dstWidth, dstHeight);
data.mGraphicBuffer = textureClient;
videoImage->SetData(data);
// implicitly releases last image
mImage = image.forget();

View File

@ -15,6 +15,7 @@
#include "mozilla/Hal.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/dom/File.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h"
namespace mozilla {
@ -112,6 +113,8 @@ protected:
int mCameraAngle; // See dom/base/ScreenOrientation.h
bool mBackCamera;
bool mOrientationChanged; // True when screen rotates.
RefPtr<layers::TextureClientRecycleAllocator> mTextureClientAllocator;
};
} // namespace mozilla

View File

@ -7058,21 +7058,21 @@ GsmPDUHelperObject.prototype = {
},
/**
* Convert a semi-octet (number) to a GSM BCD char, or return empty string
* if invalid semiOctet and supressException is set to true.
* Convert a semi-octet (number) to a GSM BCD char, or return empty
* string if invalid semiOctet and suppressException is set to true.
*
* @param semiOctet
* Nibble to be converted to.
* @param [optional] supressException
* Supress exception if invalid semiOctet and supressException is set
* @param suppressException [optional]
* Suppress exception if invalid semiOctet and suppressException is set
* to true.
*
* @return GSM BCD char, or empty string.
*/
bcdChars: "0123456789*#,;",
semiOctetToBcdChar: function(semiOctet, supressException) {
if (semiOctet >= 14) {
if (supressException) {
bcdChars: "0123456789",
semiOctetToBcdChar: function(semiOctet, suppressException) {
if (semiOctet >= this.bcdChars.length) {
if (suppressException) {
return "";
} else {
throw new RangeError();
@ -7082,6 +7082,31 @@ GsmPDUHelperObject.prototype = {
return this.bcdChars.charAt(semiOctet);
},
/**
* Convert a semi-octet (number) to a GSM extended BCD char, or return empty
* string if invalid semiOctet and suppressException is set to true.
*
* @param semiOctet
* Nibble to be converted to.
* @param suppressException [optional]
* Suppress exception if invalid semiOctet and suppressException is set
* to true.
*
* @return GSM extended BCD char, or empty string.
*/
extendedBcdChars: "0123456789*#,;",
semiOctetToExtendedBcdChar: function(semiOctet, suppressException) {
if (semiOctet >= this.extendedBcdChars.length) {
if (suppressException) {
return "";
} else {
throw new RangeError();
}
}
return this.extendedBcdChars.charAt(semiOctet);
},
/**
* Read a *swapped nibble* binary coded decimal (BCD)
*
@ -7112,17 +7137,17 @@ GsmPDUHelperObject.prototype = {
},
/**
* Read a *swapped nibble* binary coded string (BCD)
* Read a *swapped nibble* binary coded decimal (BCD) string
*
* @param pairs
* Number of nibble *pairs* to read.
* @param [optional] supressException
* Supress exception if invalid semiOctet and supressException is set
* @param suppressException [optional]
* Suppress exception if invalid semiOctet and suppressException is set
* to true.
*
* @return The BCD string.
*/
readSwappedNibbleBcdString: function(pairs, supressException) {
readSwappedNibbleBcdString: function(pairs, suppressException) {
let str = "";
for (let i = 0; i < pairs; i++) {
let nibbleH = this.readHexNibble();
@ -7131,9 +7156,38 @@ GsmPDUHelperObject.prototype = {
break;
}
str += this.semiOctetToBcdChar(nibbleL, supressException);
str += this.semiOctetToBcdChar(nibbleL, suppressException);
if (nibbleH != 0x0F) {
str += this.semiOctetToBcdChar(nibbleH, supressException);
str += this.semiOctetToBcdChar(nibbleH, suppressException);
}
}
return str;
},
/**
* Read a *swapped nibble* extended binary coded decimal (BCD) string
*
* @param pairs
* Number of nibble *pairs* to read.
* @param suppressException [optional]
* Suppress exception if invalid semiOctet and suppressException is set
* to true.
*
* @return The BCD string.
*/
readSwappedNibbleExtendedBcdString: function(pairs, suppressException) {
let str = "";
for (let i = 0; i < pairs; i++) {
let nibbleH = this.readHexNibble();
let nibbleL = this.readHexNibble();
if (nibbleL == 0x0F) {
break;
}
str += this.semiOctetToExtendedBcdChar(nibbleL, suppressException);
if (nibbleH != 0x0F) {
str += this.semiOctetToExtendedBcdChar(nibbleH, suppressException);
}
}
@ -7605,7 +7659,7 @@ GsmPDUHelperObject.prototype = {
PDU_NL_IDENTIFIER_DEFAULT , PDU_NL_IDENTIFIER_DEFAULT );
return addr;
}
addr = this.readSwappedNibbleBcdString(len / 2);
addr = this.readSwappedNibbleExtendedBcdString(len / 2);
if (addr.length <= 0) {
if (DEBUG) this.context.debug("PDU error: no number provided");
return null;
@ -7955,7 +8009,7 @@ GsmPDUHelperObject.prototype = {
if (smscLength > 0) {
let smscTypeOfAddress = this.readHexOctet();
// Subtract the type-of-address octet we just read from the length.
msg.SMSC = this.readSwappedNibbleBcdString(smscLength - 1);
msg.SMSC = this.readSwappedNibbleExtendedBcdString(smscLength - 1);
if ((smscTypeOfAddress >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
msg.SMSC = '+' + msg.SMSC;
}
@ -10424,7 +10478,7 @@ ICCPDUHelperObject.prototype = {
// TOA = TON + NPI
let toa = GsmPDUHelper.readHexOctet();
let number = GsmPDUHelper.readSwappedNibbleBcdString(len - 1);
let number = GsmPDUHelper.readSwappedNibbleExtendedBcdString(len - 1);
if (number.length <= 0) {
if (DEBUG) this.context.debug("No number provided");
return "";
@ -12668,11 +12722,12 @@ ICCRecordHelperObject.prototype = {
function callback() {
let Buf = this.context.Buf;
let RIL = this.context.RIL;
let GsmPDUHelper = this.context.GsmPDUHelper;
let strLen = Buf.readInt32();
let octetLen = strLen / 2;
RIL.iccInfo.iccid =
this.context.GsmPDUHelper.readSwappedNibbleBcdString(octetLen, true);
GsmPDUHelper.readSwappedNibbleBcdString(octetLen, true);
// Consumes the remaining buffer if any.
let unReadBuffer = this.context.Buf.getReadAvailable() -
this.context.Buf.PDU_HEX_OCTET_SIZE;
@ -13961,7 +14016,7 @@ SimRecordHelperObject.prototype = {
let buf = "";
for (let i = 0; i < reformat.length; i++) {
if (reformat[i] != 0xF) {
buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
buf += GsmPDUHelper.semiOctetToExtendedBcdChar(reformat[i]);
}
if (i === 2) {
// 0-2: MCC
@ -14118,7 +14173,7 @@ SimRecordHelperObject.prototype = {
let plmnEntry = {};
for (let i = 0; i < reformat.length; i++) {
if (reformat[i] != 0xF) {
buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
buf += GsmPDUHelper.semiOctetToExtendedBcdChar(reformat[i]);
}
if (i === 2) {
// 0-2: MCC
@ -14611,7 +14666,7 @@ ICCUtilsHelperObject.prototype = {
}
} else {
let GsmPDUHelper = this.context.GsmPDUHelper;
let wildChar = GsmPDUHelper.bcdChars.charAt(0x0d);
let wildChar = GsmPDUHelper.extendedBcdChars.charAt(0x0d);
// According to 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
// the ME shall use this EF_OPL in association with the EF_PNN in place
// of any network name stored within the ME's internal list and any network

View File

@ -61,7 +61,7 @@ add_test(function test_read_dialling_number() {
return 0x81;
};
helper.readSwappedNibbleBcdString = function(len) {
helper.readSwappedNibbleExtendedBcdString = function(len) {
return str.substring(0, len);
};

View File

@ -714,10 +714,16 @@ add_test(function test_handling_iccid() {
do_check_eq(ril.iccInfo.iccid, expectedICCID);
}
// Invalid char at high nibbile + low nibbile contains 0xF.
// Invalid value 0xE at high nibbile + low nibbile contains 0xF.
do_test("9868002E90909F001519", "89860020909");
// Invalid char at low nibbile.
do_test("986800E2909090001519", "8986002090909005191");
// Invalid value 0xD at low nibbile.
do_test("986800D2909090001519", "8986002090909005191");
// Invalid value 0xC at low nibbile.
do_test("986800C2909090001519", "8986002090909005191");
// Invalid value 0xB at low nibbile.
do_test("986800B2909090001519", "8986002090909005191");
// Invalid value 0xA at low nibbile.
do_test("986800A2909090001519", "8986002090909005191");
// Valid ICCID.
do_test("98101430121181157002", "89014103211118510720");

View File

@ -386,6 +386,10 @@ TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
return texture;
}
if (aAllocFlags & ALLOC_DISALLOW_BUFFERTEXTURECLIENT) {
return nullptr;
}
if (texture) {
NS_WARNING("Failed to allocate a TextureClient, falling back to BufferTextureClient.");
}

View File

@ -71,7 +71,8 @@ class KeepAlive;
enum TextureAllocationFlags {
ALLOC_DEFAULT = 0,
ALLOC_CLEAR_BUFFER = 1,
ALLOC_CLEAR_BUFFER_WHITE = 2
ALLOC_CLEAR_BUFFER_WHITE = 2,
ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 4
};
#ifdef XP_WIN

View File

@ -23,6 +23,13 @@ class TextureClientRecycleAllocatorImp : public ISurfaceAllocator
public:
explicit TextureClientRecycleAllocatorImp(ISurfaceAllocator* aAllocator);
void SetMaxPoolSize(uint32_t aMax)
{
if (aMax > 0) {
mMaxPooledSize = aMax;
}
}
// Creates and allocates a TextureClient.
TemporaryRef<TextureClient>
CreateOrRecycleForDrawing(gfx::SurfaceFormat aFormat,
@ -125,7 +132,6 @@ TextureClientRecycleAllocatorImp::~TextureClientRecycleAllocatorImp()
MOZ_ASSERT(mInUseClients.empty());
}
TemporaryRef<TextureClient>
TextureClientRecycleAllocatorImp::CreateOrRecycleForDrawing(
gfx::SurfaceFormat aFormat,
@ -136,7 +142,8 @@ TextureClientRecycleAllocatorImp::CreateOrRecycleForDrawing(
{
// TextureAllocationFlags is actually used only by ContentClient.
// This class does not handle ConteClient's TextureClient allocation.
MOZ_ASSERT(aAllocFlags == TextureAllocationFlags::ALLOC_DEFAULT);
MOZ_ASSERT(aAllocFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
aAllocFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
MOZ_ASSERT(!(aTextureFlags & TextureFlags::RECYCLE));
aTextureFlags = aTextureFlags | TextureFlags::RECYCLE; // Set recycle flag
@ -237,6 +244,11 @@ TextureClientRecycleAllocator::~TextureClientRecycleAllocator()
mAllocator = nullptr;
}
void
TextureClientRecycleAllocator::SetMaxPoolSize(uint32_t aMax)
{
mAllocator->SetMaxPoolSize(aMax);
}
TemporaryRef<TextureClient>
TextureClientRecycleAllocator::CreateOrRecycleForDrawing(

View File

@ -32,6 +32,8 @@ public:
explicit TextureClientRecycleAllocator(ISurfaceAllocator* aAllocator);
void SetMaxPoolSize(uint32_t aMax);
// Creates and allocates a TextureClient.
TemporaryRef<TextureClient>
CreateOrRecycleForDrawing(gfx::SurfaceFormat aFormat,

View File

@ -171,6 +171,8 @@ SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
return gfx::SurfaceFormat::R8G8B8X8;
case PIXEL_FORMAT_RGB_565:
return gfx::SurfaceFormat::R5G6B5;
case HAL_PIXEL_FORMAT_YV12:
return gfx::SurfaceFormat::YUV;
default:
MOZ_CRASH("Unknown gralloc pixel format");
}
@ -230,6 +232,9 @@ GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
case gfx::SurfaceFormat::R5G6B5:
format = android::PIXEL_FORMAT_RGB_565;
break;
case gfx::SurfaceFormat::YUV:
format = HAL_PIXEL_FORMAT_YV12;
break;
case gfx::SurfaceFormat::A8:
NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
return false;

View File

@ -1496,6 +1496,11 @@ AsmJSModule::serializedSize() const
uint8_t *
AsmJSModule::serialize(uint8_t *cursor) const
{
MOZ_ASSERT(!dynamicallyLinked_);
MOZ_ASSERT(!loadedFromCache_);
MOZ_ASSERT(!profilingEnabled_);
MOZ_ASSERT(!interrupted_);
cursor = WriteBytes(cursor, &pod, sizeof(pod));
cursor = WriteBytes(cursor, code_, pod.codeBytes_);
cursor = SerializeName(cursor, globalArgumentName_);
@ -1590,6 +1595,16 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
out.loadedFromCache_ = loadedFromCache_;
out.profilingEnabled_ = profilingEnabled_;
if (profilingEnabled_) {
if (!out.profilingLabels_.resize(profilingLabels_.length()))
return false;
for (size_t i = 0; i < profilingLabels_.length(); i++) {
out.profilingLabels_[i] = DuplicateString(cx, profilingLabels_[i].get());
if (!out.profilingLabels_[i])
return false;
}
}
// We already know the exact extent of areas that need to be patched, just make sure we
// flush all of them at once.
out.setAutoFlushICacheRange();

View File

@ -645,7 +645,7 @@ class AsmJSModule
bool clone(ExclusiveContext *cx, Name *out) const;
};
typedef mozilla::UniquePtr<char, JS::FreePolicy> ProfilingLabel;
typedef mozilla::UniquePtr<char[], JS::FreePolicy> ProfilingLabel;
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
// Function information to add to the VTune JIT profiler following linking.

View File

@ -9165,9 +9165,6 @@ EstablishPreconditions(ExclusiveContext *cx, AsmJSParser &parser)
if (parser.pc->isArrowFunction())
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by arrow function context");
if (ParallelCompilationEnabled(cx))
EnsureHelperThreadsInitialized(cx);
return true;
}

View File

@ -651,9 +651,10 @@ function ArrayIteratorIdentity() {
}
function ArrayIteratorNext() {
// FIXME: Cross-compartment wrapper ArrayIterator objects should pass this test. Bug 1111170.
if (!IsObject(this) || !IsArrayIterator(this))
ThrowError(JSMSG_INCOMPATIBLE_METHOD, "ArrayIterator", "next", ToString(this));
if (!IsObject(this) || !IsArrayIterator(this)) {
return callFunction(CallArrayIteratorMethodIfWrapped, this,
"ArrayIteratorNext");
}
var a = UnsafeGetReservedSlot(this, ARRAY_ITERATOR_SLOT_ITERATED_OBJECT);
var index = UnsafeGetReservedSlot(this, ARRAY_ITERATOR_SLOT_NEXT_INDEX);

View File

@ -2058,8 +2058,8 @@ bool
GlobalObject::initIntlObject(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject Intl(cx);
Intl = NewObjectWithGivenProto(cx, &IntlClass, global->getOrCreateObjectPrototype(cx),
global, SingletonObject);
RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
Intl = NewObjectWithGivenProto(cx, &IntlClass, proto, global, SingletonObject);
if (!Intl)
return false;

View File

@ -207,9 +207,10 @@ function StringIteratorIdentity() {
}
function StringIteratorNext() {
// FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 1111170.
if (!IsObject(this) || !IsStringIterator(this))
ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this));
if (!IsObject(this) || !IsStringIterator(this)) {
return callFunction(CallStringIteratorMethodIfWrapped, this,
"StringIteratorNext");
}
var S = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_ITERATED_OBJECT);
var index = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX);

View File

@ -0,0 +1,11 @@
load(libdir + "asm.js");
// Single-step profiling currently only works in the ARM simulator
if (!getBuildConfiguration()["arm-simulator"])
quit();
enableSPSProfiling();
enableSingleStepProfiling();
var m = asmCompile(USE_ASM + 'function f() {} return f');
asmLink(m)();
asmLink(m)();

View File

@ -1,8 +1,5 @@
// Iterators from another compartment work with their own .next method
// when called from another compartment, but not with the other
// compartment's .next method.
// FIXME: 'next' should work cross-realm. Bug 924059.
// Iterators from another compartment work with both their own .next method
// with the other compartment's .next method.
load(libdir + "asserts.js");
load(libdir + "iteration.js");
@ -10,4 +7,4 @@ load(libdir + "iteration.js");
var g = newGlobal();
g.eval(`var it = [1, 2][${uneval(std_iterator)}]();`);
assertIteratorNext(g.it, 1);
assertThrowsInstanceOf([][std_iterator]().next.bind(g.it), TypeError)
assertDeepEq([][std_iterator]().next.call(g.it), { value: 2, done: false })

View File

@ -0,0 +1,7 @@
try {
gcparam("maxBytes", gcparam("gcBytes"));
eval("\
gczeal(2, 1);\
newGlobal();\
")
} catch (e) {}

View File

@ -0,0 +1,5 @@
gczeal(14);
b = {};
b.__proto__ = evalcx("lazy");
(function m(b) {})(b.Intl.Collator(0))

View File

@ -571,6 +571,9 @@ JS_Init(void)
return false;
#endif // EXPOSE_INTL_API
if (!CreateHelperThreadsState())
return false;
jsInitState = Running;
return true;
}
@ -590,7 +593,7 @@ JS_ShutDown(void)
}
#endif
HelperThreadState().finish();
DestroyHelperThreadsState();
PRMJ_NowShutdown();

View File

@ -3492,9 +3492,6 @@ GCHelperState::init()
if (!(done = PR_NewCondVar(rt->gc.lock)))
return false;
if (CanUseExtraThreads())
HelperThreadState().ensureInitialized();
return true;
}
@ -5501,7 +5498,8 @@ GCRuntime::endSweepPhase(bool lastGC)
ZoneList zones;
for (GCZonesIter zone(rt); !zone.done(); zone.next())
zones.append(zone);
sweepBackgroundThings(zones, MainThread);
if (!zones.isEmpty())
sweepBackgroundThings(zones, MainThread);
/*
* Destroy arenas after we finished the sweeping so finalizers can

View File

@ -5901,16 +5901,16 @@ main(int argc, char **argv, char **envp)
if (op.getBoolOption("no-threads"))
js::DisableExtraThreads();
// Start the engine.
if (!JS_Init())
return 1;
// The fake thread count must be set before initializing the Runtime,
// which spins up the thread pool.
int32_t threadCount = op.getIntOption("thread-count");
if (threadCount >= 0)
SetFakeCPUCount(threadCount);
// Start the engine.
if (!JS_Init())
return 1;
size_t nurseryBytes = JS::DefaultNurseryBytes;
nurseryBytes = op.getIntOption("nursery-size") * 1024L * 1024L;

View File

@ -7,10 +7,21 @@ function TestArrayIteratorPrototypeConfusion() {
throw new Error("Call did not throw");
} catch (e) {
assertEq(e instanceof TypeError, true);
assertEq(e.message, "ArrayIterator next called on incompatible [object Array Iterator]");
assertEq(e.message, "CallArrayIteratorMethodIfWrapped method called on incompatible Array Iterator");
}
}
TestArrayIteratorPrototypeConfusion();
// Tests that we can use %ArrayIteratorPrototype%.next on a
// cross-compartment iterator.
function TestArrayIteratorWrappers() {
var iter = [][Symbol.iterator]();
assertDeepEq(iter.next.call(newGlobal().eval('[5][Symbol.iterator]()')),
{ value: 5, done: false })
}
if (typeof newGlobal === "function") {
TestArrayIteratorWrappers();
}
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -0,0 +1,27 @@
// Test that we can't confuse %StringIteratorPrototype% for a
// StringIterator object.
function TestStringIteratorPrototypeConfusion() {
var iter = ""[Symbol.iterator]();
try {
iter.next.call(Object.getPrototypeOf(iter))
throw new Error("Call did not throw");
} catch (e) {
assertEq(e instanceof TypeError, true);
assertEq(e.message, "CallStringIteratorMethodIfWrapped method called on incompatible String Iterator");
}
}
TestStringIteratorPrototypeConfusion();
// Tests that we can use %StringIteratorPrototype%.next on a
// cross-compartment iterator.
function TestStringIteratorWrappers() {
var iter = ""[Symbol.iterator]();
assertDeepEq(iter.next.call(newGlobal().eval('"x"[Symbol.iterator]()')),
{ value: "x", done: false })
}
if (typeof newGlobal === "function") {
TestStringIteratorWrappers();
}
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -28,19 +28,32 @@ using mozilla::DebugOnly;
namespace js {
GlobalHelperThreadState gHelperThreadState;
GlobalHelperThreadState *gHelperThreadState = nullptr;
} // namespace js
void
js::EnsureHelperThreadsInitialized(ExclusiveContext *cx)
bool
js::CreateHelperThreadsState()
{
// If 'cx' is not a JSContext, we are already off the main thread and the
// helper threads would have already been initialized.
if (!cx->isJSContext())
return;
MOZ_ASSERT(!gHelperThreadState);
gHelperThreadState = js_new<GlobalHelperThreadState>();
return gHelperThreadState != nullptr;
}
HelperThreadState().ensureInitialized();
void
js::DestroyHelperThreadsState()
{
MOZ_ASSERT(gHelperThreadState);
gHelperThreadState->finish();
js_delete(gHelperThreadState);
gHelperThreadState = nullptr;
}
void
js::EnsureHelperThreadsInitialized()
{
MOZ_ASSERT(gHelperThreadState);
gHelperThreadState->ensureInitialized();
}
static size_t
@ -85,8 +98,6 @@ js::StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData)
bool
js::StartOffThreadIonCompile(JSContext *cx, jit::IonBuilder *builder)
{
EnsureHelperThreadsInitialized(cx);
AutoLockHelperThreadState lock;
if (!HelperThreadState().ionWorklist().append(builder))
@ -309,8 +320,6 @@ js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &optio
// which could require barriers on the atoms compartment.
gc::AutoSuppressGC suppress(cx);
EnsureHelperThreadsInitialized(cx);
JS::CompartmentOptions compartmentOptions(cx->compartment()->options());
compartmentOptions.setZone(JS::FreshZone);
compartmentOptions.setInvisibleToDebugger(true);
@ -1216,8 +1225,6 @@ HelperThread::handleCompressionWorkload()
bool
js::StartOffThreadCompression(ExclusiveContext *cx, SourceCompressionTask *task)
{
EnsureHelperThreadsInitialized(cx);
AutoLockHelperThreadState lock;
if (!HelperThreadState().compressionWorklist().append(task)) {

View File

@ -272,8 +272,10 @@ class GlobalHelperThreadState
static inline GlobalHelperThreadState &
HelperThreadState()
{
extern GlobalHelperThreadState gHelperThreadState;
return gHelperThreadState;
extern GlobalHelperThreadState *gHelperThreadState;
MOZ_ASSERT(gHelperThreadState);
return *gHelperThreadState;
}
/* Individual helper thread, one allocated per core. */
@ -343,9 +345,17 @@ struct HelperThread
/* Methods for interacting with helper threads. */
// Create data structures used by helper threads.
bool
CreateHelperThreadsState();
// Destroy data structures used by helper threads.
void
DestroyHelperThreadsState();
// Initialize helper threads unless already initialized.
void
EnsureHelperThreadsInitialized(ExclusiveContext *cx);
EnsureHelperThreadsInitialized();
// This allows the JS shell to override GetCPUCount() when passed the
// --thread-count=N option.

View File

@ -279,6 +279,9 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
if (!threadPool.init())
return false;
if (CanUseExtraThreads())
EnsureHelperThreadsInitialized();
if (!gc.init(maxbytes, maxNurseryBytes))
return false;

View File

@ -1102,9 +1102,14 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("NewArrayIterator", intrinsic_NewArrayIterator, 0,0),
JS_FN("IsArrayIterator", intrinsic_IsArrayIterator, 1,0),
JS_FN("CallArrayIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<ArrayIteratorObject>>, 2,0),
JS_FN("NewStringIterator", intrinsic_NewStringIterator, 0,0),
JS_FN("IsStringIterator", intrinsic_IsStringIterator, 1,0),
JS_FN("CallStringIteratorMethodIfWrapped",
CallNonGenericSelfhostedMethod<Is<StringIteratorObject>>, 2,0),
JS_FN("IsStarGeneratorObject", intrinsic_IsStarGeneratorObject, 1,0),
JS_FN("StarGeneratorObjectIsClosed", intrinsic_StarGeneratorObjectIsClosed, 1,0),

View File

@ -1259,8 +1259,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
if (deltaX) {
for (line_iterator line = begin_lines(), end = end_lines();
line != end; line++) {
SlideLine(state, line, -deltaX);
line->mContainerWidth = containerWidth;
UpdateLineContainerWidth(line, containerWidth);
}
for (nsIFrame* f = mFloats.FirstChild(); f; f = f->GetNextSibling()) {
nsPoint physicalDelta(deltaX, 0);
@ -2808,6 +2807,30 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
// Adjust line state
aLine->SlideBy(aDeltaBCoord, aState.mContainerWidth);
// Adjust the frames in the line
MoveChildFramesOfLine(aLine, aDeltaBCoord);
}
void
nsBlockFrame::UpdateLineContainerWidth(nsLineBox* aLine,
nscoord aNewContainerWidth)
{
if (aNewContainerWidth == aLine->mContainerWidth) {
return;
}
// Adjust line state
nscoord widthDelta = aLine->UpdateContainerWidth(aNewContainerWidth);
// Changing container width only matters if writing mode is vertical-rl
if (GetWritingMode().IsVerticalRL()) {
MoveChildFramesOfLine(aLine, widthDelta);
}
}
void
nsBlockFrame::MoveChildFramesOfLine(nsLineBox* aLine, nscoord aDeltaBCoord)
{
// Adjust the frames in the line
nsIFrame* kid = aLine->mFirstChild;
if (!kid) {

View File

@ -414,6 +414,12 @@ protected:
void SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDeltaBCoord);
void UpdateLineContainerWidth(nsLineBox* aLine,
nscoord aNewContainerWidth);
// helper for SlideLine and UpdateLineContainerWidth
void MoveChildFramesOfLine(nsLineBox* aLine, nscoord aDeltaBCoord);
void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics,

View File

@ -42,6 +42,18 @@ public:
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
virtual mozilla::WritingMode GetWritingMode() const MOZ_OVERRIDE
{
nsIContent* rootElem = GetContent();
if (rootElem) {
nsIFrame* rootElemFrame = rootElem->GetPrimaryFrame();
if (rootElemFrame) {
return rootElemFrame->GetWritingMode();
}
}
return nsIFrame::GetWritingMode();
}
#ifdef DEBUG
virtual void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) MOZ_OVERRIDE;

View File

@ -507,6 +507,14 @@ public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
virtual mozilla::WritingMode GetWritingMode() const MOZ_OVERRIDE
{
if (mHelper.mScrolledFrame) {
return mHelper.mScrolledFrame->GetWritingMode();
}
return nsIFrame::GetWritingMode();
}
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) MOZ_OVERRIDE {

View File

@ -611,7 +611,7 @@ public:
/**
* The frame's writing-mode, used for logical layout computations.
*/
mozilla::WritingMode GetWritingMode() const {
virtual mozilla::WritingMode GetWritingMode() const {
return mozilla::WritingMode(StyleContext());
}

View File

@ -247,8 +247,11 @@ nsLineBox::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
str += nsPrintfCString("bm=%d ", GetCarriedOutBEndMargin().get());
}
nsRect bounds = GetPhysicalBounds();
str += nsPrintfCString("{%d,%d,%d,%d} ",
bounds.x, bounds.y, bounds.width, bounds.height);
str += nsPrintfCString("{%d,%d,%d,%d} {%d,%d,%d,%d;cw=%d} ",
bounds.x, bounds.y, bounds.width, bounds.height,
mBounds.IStart(mWritingMode), mBounds.BStart(mWritingMode),
mBounds.ISize(mWritingMode), mBounds.BSize(mWritingMode),
mContainerWidth);
if (mData &&
(!mData->mOverflowAreas.VisualOverflow().IsEqualEdges(bounds) ||
!mData->mOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds))) {

View File

@ -481,6 +481,26 @@ public:
}
}
// Container-width for the line is changing (and therefore if writing mode
// was vertical-rl, the line will move physically; this is like SlideBy,
// but it is the container width instead of the line's own logical coord
// that is changing.
nscoord UpdateContainerWidth(nscoord aNewContainerWidth)
{
NS_ASSERTION(mContainerWidth != -1, "container width not set");
nscoord delta = mContainerWidth - aNewContainerWidth;
mContainerWidth = aNewContainerWidth;
// this has a physical-coordinate effect only in vertical-rl mode
if (mWritingMode.IsVerticalRL() && mData) {
nsPoint physicalDelta = mozilla::LogicalPoint(mWritingMode, 0, delta).
GetPhysicalPoint(mWritingMode, 0);
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
mData->mOverflowAreas.Overflow(otype) += physicalDelta;
}
}
return delta;
}
void IndentBy(nscoord aDICoord, nscoord aContainerWidth) {
NS_ASSERTION(aContainerWidth == mContainerWidth || mContainerWidth == -1,
"container width doesn't match");

View File

@ -941,7 +941,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// We might as well allow zero-width floats to be placed, though.
availableISize = 0;
}
placedFloat = AddFloat(outOfFlowFrame, availableISize);
placedFloat = mBaseLineLayout->AddFloat(outOfFlowFrame, availableISize);
NS_ASSERTION(!(outOfFlowFrame->GetType() == nsGkAtoms::letterFrame &&
GetFirstLetterStyleOK()),
"FirstLetterStyle set on line with floating first letter");
@ -2532,6 +2532,61 @@ nsLineLayout::ComputeFrameJustification(PerSpanData* aPSD,
return result;
}
void
nsLineLayout::AdvanceAnnotationInlineBounds(PerFrameData* aPFD,
nscoord aContainerWidth,
nscoord aDeltaICoord,
nscoord aDeltaISize)
{
MOZ_ASSERT(aPFD->mFrame->GetType() == nsGkAtoms::rubyTextFrame ||
aPFD->mFrame->GetType() == nsGkAtoms::rubyTextContainerFrame);
MOZ_ASSERT(aPFD->mSpan, "rt and rtc should have span.");
WritingMode lineWM = mRootSpan->mWritingMode;
WritingMode frameWM = aPFD->mSpan->mWritingMode;
LogicalRect bounds = aPFD->mFrame->GetLogicalRect(aContainerWidth);
bounds = bounds.ConvertTo(lineWM, frameWM, aContainerWidth);
bounds.IStart(lineWM) += aDeltaICoord;
bounds.ISize(lineWM) += aDeltaISize;
aPFD->mBounds = bounds.ConvertTo(frameWM, lineWM, aContainerWidth);
aPFD->mFrame->SetRect(frameWM, aPFD->mBounds, aContainerWidth);
}
/**
* This function applies the changes of icoord and isize caused by
* justification to annotations of the given frame.
* aPFD must be one of the frames in aContainingSpan.
*/
void
nsLineLayout::ApplyLineJustificationToAnnotations(PerFrameData* aPFD,
PerSpanData* aContainingSpan,
nscoord aDeltaICoord,
nscoord aDeltaISize)
{
PerFrameData* pfd = aPFD->mNextAnnotation;
nscoord containerWidth = ContainerWidthForSpan(aContainingSpan);
while (pfd) {
AdvanceAnnotationInlineBounds(pfd, containerWidth,
aDeltaICoord, aDeltaISize);
// There are two cases where an annotation frame has siblings which
// do not attached to a ruby base-level frame:
// 1. there's an intra-annotation whitespace which has no intra-base
// white-space to pair with;
// 2. there are not enough ruby bases to be paired with annotations.
// In these cases, their size should not be affected, but we still
// need to move them so that they won't overlap other frames.
PerFrameData* sibling = pfd->mNext;
while (sibling && !sibling->GetFlag(PFD_ISLINKEDTOBASE)) {
AdvanceAnnotationInlineBounds(sibling, containerWidth,
aDeltaICoord + aDeltaISize, 0);
sibling = sibling->mNext;
}
pfd = pfd->mNextAnnotation;
}
}
nscoord
nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD,
JustificationApplicationState& aState)
@ -2570,6 +2625,7 @@ nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD,
pfd->mBounds.ISize(lineWM) += dw;
ApplyLineJustificationToAnnotations(pfd, aPSD, deltaICoord, dw);
deltaICoord += dw;
pfd->mFrame->SetRect(lineWM, pfd->mBounds, ContainerWidthForSpan(aPSD));
}

View File

@ -670,6 +670,16 @@ protected:
int32_t ComputeFrameJustification(PerSpanData* psd,
JustificationComputationState& aState);
void AdvanceAnnotationInlineBounds(PerFrameData* aPFD,
nscoord aContainerWidth,
nscoord aDeltaICoord,
nscoord aDeltaISize);
void ApplyLineJustificationToAnnotations(PerFrameData* aPFD,
PerSpanData* aContainingSpan,
nscoord aDeltaICoord,
nscoord aDeltaISize);
// Apply justification. The return value is the amount by which the width of
// the span corresponding to aPSD got increased due to justification.
nscoord ApplyFrameJustification(

View File

@ -212,7 +212,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
kidFrame, availableSpace);
// Reflow the frame
kidReflowState.SetComputedHeight(aReflowState.ComputedHeight());
kidReflowState.SetComputedBSize(aReflowState.ComputedBSize());
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
0, 0, 0, aStatus);
kidBSize = kidDesiredSize.BSize(wm);
@ -223,7 +223,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
}
}
NS_ASSERTION(aReflowState.AvailableWidth() != NS_UNCONSTRAINEDSIZE,
NS_ASSERTION(aReflowState.AvailableISize() != NS_UNCONSTRAINEDSIZE,
"shouldn't happen anymore");
// Return the max size as our desired size

View File

@ -38,6 +38,15 @@ public:
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
virtual mozilla::WritingMode GetWritingMode() const MOZ_OVERRIDE
{
nsIFrame* firstChild = mFrames.FirstChild();
if (firstChild) {
return firstChild->GetWritingMode();
}
return nsIFrame::GetWritingMode();
}
#ifdef DEBUG
virtual void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) MOZ_OVERRIDE;

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="common.css">
<style>
ruby div {
width: 10px; height: 10px;
background-color: grey;
}
.left { float: left; }
.right { float: right; }
</style>
</head>
<body>
<div><ruby><rb><div class="left"></div>hello world</rb><rt>hello world</rt></ruby></div>
<div><ruby><rb><div class="left"></div>hello world</rb><rt>hello world</rt></ruby></div>
<div><ruby><rb><div class="right"></div>hello world</rb><rt>hello world</rt></ruby></div>
<div><ruby><rb><div class="right"></div>hello world</rb><rt>hello world</rt></ruby></div>
</body>
</html>

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="common.css">
<style>
ruby div {
width: 10px; height: 10px;
background-color: grey;
}
.left { float: left; }
.right { float: right; }
</style>
</head>
<body>
<div><ruby><rb>hello world</rb><rt><div class="left"></div>hello world</rt></ruby></div>
<div><ruby><rb>hello world</rb><rt>hello<div class="left"></div> world</rt></ruby></div>
<div><ruby><rb>hello world</rb><rt><div class="right"></div>hello world</rt></ruby></div>
<div><ruby><rb>hello world</rb><rt>hello<div class="right"></div> world</rt></ruby></div>
</body>
</html>

View File

@ -11,6 +11,7 @@ default-preferences pref(layout.css.ruby.enabled,true)
== dynamic-removal-1.html dynamic-removal-1-ref.html
== dynamic-removal-2.html dynamic-removal-2-ref.html
fuzzy-if(winWidget,28,1) == dynamic-removal-3.html dynamic-removal-3-ref.html # bug 1111891
== float-handling.html float-handling-ref.html
== inlinize-blocks-1.html inlinize-blocks-1-ref.html
== inlinize-blocks-2.html inlinize-blocks-2-ref.html
== inlinize-blocks-3.html inlinize-blocks-3-ref.html

View File

@ -1060,19 +1060,15 @@ WebrtcVideoConduit::SendVideoFrame(unsigned char* video_frame,
return kMediaConduitMalformedArgument;
}
webrtc::RawVideoType type;
switch (video_type) {
case kVideoI420:
type = webrtc::kVideoI420;
break;
case kVideoNV21:
type = webrtc::kVideoNV21;
break;
default:
CSFLogError(logTag, "%s VideoType Invalid. Only 1420 and NV21 Supported",__FUNCTION__);
MOZ_ASSERT(PR_FALSE);
return kMediaConduitMalformedArgument;
// NOTE: update when common_types.h changes
if (video_type > kVideoBGRA) {
CSFLogError(logTag, "%s VideoType %d Invalid", __FUNCTION__, video_type);
MOZ_ASSERT(PR_FALSE);
return kMediaConduitMalformedArgument;
}
// RawVideoType == VideoType
webrtc::RawVideoType type = static_cast<webrtc::RawVideoType>((int)video_type);
//Transmission should be enabled before we insert any frames.
if(!mEngineTransmitting)
{

View File

@ -1175,15 +1175,36 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
if (format == ImageFormat::GRALLOC_PLANAR_YCBCR) {
layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(img);
android::sp<android::GraphicBuffer> graphicBuffer = nativeImage->GetGraphicBuffer();
int pixelFormat = graphicBuffer->getPixelFormat(); /* PixelFormat is an enum == int */
mozilla::VideoType destFormat;
switch (pixelFormat) {
case HAL_PIXEL_FORMAT_YV12:
// all android must support this
destFormat = mozilla::kVideoYV12;
break;
case layers::GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP:
destFormat = mozilla::kVideoNV21;
break;
case layers::GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_P:
destFormat = mozilla::kVideoI420;
break;
default:
// XXX Bug NNNNNNN
// use http://mxr.mozilla.org/mozilla-central/source/content/media/omx/I420ColorConverterHelper.cpp
// to convert unknown types (OEM-specific) to I420
MOZ_MTLOG(ML_ERROR, "Un-handled GRALLOC buffer type:" << pixelFormat);
MOZ_CRASH();
}
void *basePtr;
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_MASK, &basePtr);
uint32_t width = graphicBuffer->getWidth();
uint32_t height = graphicBuffer->getHeight();
// XXX gralloc buffer's width and stride could be different depends on implementations.
conduit->SendVideoFrame(static_cast<unsigned char*>(basePtr),
I420SIZE(width, height),
width,
height,
mozilla::kVideoNV21, 0);
destFormat, 0);
graphicBuffer->unlock();
} else
#endif

View File

@ -241,6 +241,28 @@ int ConvertToI420(VideoType src_video_type,
dst_width = dst_frame->height();
dst_height =dst_frame->width();
}
#ifdef WEBRTC_GONK
if (src_video_type == kYV12) {
// In gralloc buffer, yv12 color format's cb and cr's strides are aligned
// to 16 Bytes boundary. See /system/core/include/system/graphics.h
int stride_y = src_width;
int stride_uv = (((stride_y + 1) / 2) + 15) & ~0x0F;
return libyuv::I420Rotate(src_frame,
stride_y,
src_frame + (stride_y * src_height) + (stride_uv * ((src_height + 1) / 2)),
stride_uv,
src_frame + (stride_y * src_height),
stride_uv,
dst_frame->buffer(kYPlane),
dst_frame->stride(kYPlane),
dst_frame->buffer(kUPlane),
dst_frame->stride(kUPlane),
dst_frame->buffer(kVPlane),
dst_frame->stride(kVPlane),
src_width, src_height,
ConvertRotationMode(rotation));
}
#endif
return libyuv::ConvertToI420(src_frame, sample_size,
dst_frame->buffer(kYPlane),
dst_frame->stride(kYPlane),

View File

@ -53,8 +53,10 @@
#include "client/linux/crash_generation/client_info.h"
#include "client/linux/crash_generation/crash_generation_server.h"
#include "client/linux/handler/exception_handler.h"
#include "common/linux/eintr_wrapper.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#elif defined(XP_SOLARIS)
#include "client/solaris/handler/exception_handler.h"
@ -956,6 +958,13 @@ bool MinidumpCallback(
}
#endif
_exit(1);
#ifdef MOZ_WIDGET_ANDROID
} else {
// We need to wait on the 'am start' command above to finish, otherwise everything will
// be killed by the ActivityManager as soon as the signal handler exits
int status;
unused << HANDLE_EINTR(sys_waitpid(pid, &status, __WALL));
#endif
}
#endif // XP_MACOSX
#endif // XP_UNIX

View File

@ -493,6 +493,9 @@ XRE_InitChildProcess(int aArgc,
// Content processes need the XPCOM/chromium frankenventloop
uiLoopType = MessageLoop::TYPE_MOZILLA_CHILD;
break;
case GeckoProcessType_GMPlugin:
uiLoopType = MessageLoop::TYPE_DEFAULT;
break;
default:
uiLoopType = MessageLoop::TYPE_UI;
break;
@ -741,7 +744,7 @@ struct RunnableMethodTraits<ContentChild>
void
XRE_ShutdownChildProcess()
{
NS_ABORT_IF_FALSE(MessageLoopForUI::current(), "Wrong thread!");
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Wrong thread!");
mozilla::DebugOnly<MessageLoop*> ioLoop = XRE_GetIOMessageLoop();
NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order");

View File

@ -807,12 +807,18 @@ namespace mozilla {
bool ProcessNextEvent()
{
if (!nsAppShell::gAppShell) {
return false;
}
return nsAppShell::gAppShell->ProcessNextNativeEvent(true) ? true : false;
}
void NotifyEvent()
{
nsAppShell::gAppShell->NotifyNativeEvent();
if (nsAppShell::gAppShell) {
nsAppShell::gAppShell->NotifyNativeEvent();
}
}
}