mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to central, a=merge
This commit is contained in:
commit
25e2d200fc
@ -85,7 +85,8 @@ MediaSourceDecoder::GetSeekable()
|
||||
} else if (duration > 0 && mozilla::IsInfinite(duration)) {
|
||||
media::TimeIntervals buffered = GetBuffered();
|
||||
if (buffered.Length()) {
|
||||
seekable += media::TimeInterval(buffered.GetStart(), buffered.GetEnd());
|
||||
seekable +=
|
||||
media::TimeInterval(media::TimeUnit::FromSeconds(0), buffered.GetEnd());
|
||||
}
|
||||
} else {
|
||||
seekable += media::TimeInterval(media::TimeUnit::FromSeconds(0),
|
||||
|
@ -527,8 +527,7 @@ AudioContext::CreatePeriodicWave(const Float32Array& aRealData,
|
||||
aImagData.ComputeLengthAndData();
|
||||
|
||||
if (aRealData.Length() != aImagData.Length() ||
|
||||
aRealData.Length() == 0 ||
|
||||
aRealData.Length() > 4096) {
|
||||
aRealData.Length() == 0) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ PeriodicWave::PeriodicWave(AudioContext* aContext,
|
||||
|
||||
// Caller should have checked this and thrown.
|
||||
MOZ_ASSERT(aLength > 0);
|
||||
MOZ_ASSERT(aLength <= 4096);
|
||||
mLength = aLength;
|
||||
|
||||
// Copy coefficient data. The two arrays share an allocation.
|
||||
|
@ -31,8 +31,8 @@
|
||||
#include <cmath>
|
||||
#include "mozilla/FFTBlock.h"
|
||||
|
||||
const unsigned PeriodicWaveSize = 4096; // This must be a power of two.
|
||||
const unsigned NumberOfRanges = 36; // There should be 3 * log2(PeriodicWaveSize) 1/3 octave ranges.
|
||||
const unsigned MinPeriodicWaveSize = 4096; // This must be a power of two.
|
||||
const unsigned MaxPeriodicWaveSize = 8192; // This must be a power of two.
|
||||
const float CentsPerRange = 1200 / 3; // 1/3 Octave.
|
||||
|
||||
using namespace mozilla;
|
||||
@ -46,12 +46,11 @@ PeriodicWave::create(float sampleRate,
|
||||
const float* imag,
|
||||
size_t numberOfComponents)
|
||||
{
|
||||
bool isGood = real && imag && numberOfComponents > 0 &&
|
||||
numberOfComponents <= PeriodicWaveSize;
|
||||
bool isGood = real && imag && numberOfComponents > 0;
|
||||
MOZ_ASSERT(isGood);
|
||||
if (isGood) {
|
||||
RefPtr<PeriodicWave> periodicWave =
|
||||
new PeriodicWave(sampleRate);
|
||||
new PeriodicWave(sampleRate, numberOfComponents);
|
||||
periodicWave->createBandLimitedTables(real, imag, numberOfComponents);
|
||||
return periodicWave.forget();
|
||||
}
|
||||
@ -62,7 +61,7 @@ already_AddRefed<PeriodicWave>
|
||||
PeriodicWave::createSine(float sampleRate)
|
||||
{
|
||||
RefPtr<PeriodicWave> periodicWave =
|
||||
new PeriodicWave(sampleRate);
|
||||
new PeriodicWave(sampleRate, MinPeriodicWaveSize);
|
||||
periodicWave->generateBasicWaveform(OscillatorType::Sine);
|
||||
return periodicWave.forget();
|
||||
}
|
||||
@ -71,7 +70,7 @@ already_AddRefed<PeriodicWave>
|
||||
PeriodicWave::createSquare(float sampleRate)
|
||||
{
|
||||
RefPtr<PeriodicWave> periodicWave =
|
||||
new PeriodicWave(sampleRate);
|
||||
new PeriodicWave(sampleRate, MinPeriodicWaveSize);
|
||||
periodicWave->generateBasicWaveform(OscillatorType::Square);
|
||||
return periodicWave.forget();
|
||||
}
|
||||
@ -80,7 +79,7 @@ already_AddRefed<PeriodicWave>
|
||||
PeriodicWave::createSawtooth(float sampleRate)
|
||||
{
|
||||
RefPtr<PeriodicWave> periodicWave =
|
||||
new PeriodicWave(sampleRate);
|
||||
new PeriodicWave(sampleRate, MinPeriodicWaveSize);
|
||||
periodicWave->generateBasicWaveform(OscillatorType::Sawtooth);
|
||||
return periodicWave.forget();
|
||||
}
|
||||
@ -89,18 +88,25 @@ already_AddRefed<PeriodicWave>
|
||||
PeriodicWave::createTriangle(float sampleRate)
|
||||
{
|
||||
RefPtr<PeriodicWave> periodicWave =
|
||||
new PeriodicWave(sampleRate);
|
||||
new PeriodicWave(sampleRate, MinPeriodicWaveSize);
|
||||
periodicWave->generateBasicWaveform(OscillatorType::Triangle);
|
||||
return periodicWave.forget();
|
||||
}
|
||||
|
||||
PeriodicWave::PeriodicWave(float sampleRate)
|
||||
PeriodicWave::PeriodicWave(float sampleRate, size_t numberOfComponents)
|
||||
: m_sampleRate(sampleRate)
|
||||
, m_periodicWaveSize(PeriodicWaveSize)
|
||||
, m_numberOfRanges(NumberOfRanges)
|
||||
, m_centsPerRange(CentsPerRange)
|
||||
{
|
||||
float nyquist = 0.5 * m_sampleRate;
|
||||
|
||||
if (numberOfComponents <= MinPeriodicWaveSize) {
|
||||
m_periodicWaveSize = MinPeriodicWaveSize;
|
||||
} else {
|
||||
unsigned npow2 = powf(2.0f, floorf(logf(numberOfComponents - 1.0)/logf(2.0f) + 1.0f));
|
||||
m_periodicWaveSize = std::min(MaxPeriodicWaveSize, npow2);
|
||||
}
|
||||
|
||||
m_numberOfRanges = (unsigned)(3.0f*logf(m_periodicWaveSize)/logf(2.0f));
|
||||
m_lowestFundamentalFrequency = nyquist / maxNumberOfPartials();
|
||||
m_rateScale = m_periodicWaveSize / m_sampleRate;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
explicit PeriodicWave(float sampleRate);
|
||||
explicit PeriodicWave(float sampleRate, size_t numberOfComponents);
|
||||
~PeriodicWave() {}
|
||||
|
||||
void generateBasicWaveform(mozilla::dom::OscillatorType);
|
||||
|
@ -37,9 +37,9 @@ addLoadEvent(function() {
|
||||
expectException(function() {
|
||||
ac.createPeriodicWave(new Float32Array(0), new Float32Array(0));
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectException(function() {
|
||||
expectNoException(function() {
|
||||
ac.createPeriodicWave(new Float32Array(4097), new Float32Array(4097));
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
});
|
||||
|
||||
runTest();
|
||||
});
|
||||
|
@ -136,7 +136,8 @@ public:
|
||||
TrackID aId,
|
||||
StreamTime aDesiredTime) override
|
||||
{
|
||||
NS_WARN_IF_FALSE(aDesiredTime <= aSource->GetEndOfAppendedData(aId),
|
||||
NS_WARN_IF_FALSE(!aSource->FindTrack(aId) ||
|
||||
aDesiredTime <= aSource->GetEndOfAppendedData(aId),
|
||||
"MediaEngineDefaultAudioSource data underrun");
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@ support-files =
|
||||
test_bug1004814.html
|
||||
worker_bug1004814.js
|
||||
|
||||
[browser_test_toolbars_visibility.js]
|
||||
support-files =
|
||||
test_new_window_from_content_child.html
|
||||
[browser_bug1008941_dismissGeolocationHanger.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_test__content.js]
|
||||
|
187
dom/tests/browser/browser_test_toolbars_visibility.js
Normal file
187
dom/tests/browser/browser_test_toolbars_visibility.js
Normal file
@ -0,0 +1,187 @@
|
||||
// Tests that toolbars have proper visibility when opening a new window
|
||||
// in either content or chrome context.
|
||||
|
||||
const CONTENT_PAGE = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
|
||||
|
||||
/**
|
||||
* This function retrieves the visibility state of the toolbars of a
|
||||
* window within the content context.
|
||||
*
|
||||
* @param aBrowser (<xul:browser>)
|
||||
* The browser to query for toolbar visibility states
|
||||
* @returns Promise
|
||||
* A promise that resolves when the toolbar state is retrieved
|
||||
* within the content context, which value is an object that holds
|
||||
* the visibility state of the toolbars
|
||||
*/
|
||||
function getToolbarsFromBrowserContent(aBrowser) {
|
||||
return ContentTask.spawn(aBrowser, {}, function*() {
|
||||
return {
|
||||
toolbar: content.toolbar.visible,
|
||||
menubar: content.menubar.visible,
|
||||
personalbar: content.personalbar.visible,
|
||||
statusbar: content.statusbar.visible,
|
||||
locationbar: content.locationbar.visible,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function retrieves the visibility state of the toolbars of a
|
||||
* window within the chrome context.
|
||||
*
|
||||
* @param win
|
||||
* the chrome privileged window
|
||||
* @returns object
|
||||
* an object that holds the visibility state of the toolbars
|
||||
*/
|
||||
function getToolbarsFromWindowChrome(win) {
|
||||
return {
|
||||
toolbar: win.toolbar.visible,
|
||||
menubar: win.menubar.visible,
|
||||
personalbar: win.personalbar.visible,
|
||||
statusbar: win.statusbar.visible,
|
||||
locationbar: win.locationbar.visible,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with default parameters.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testDefaultToolbars(toolbars) {
|
||||
ok(toolbars.locationbar,
|
||||
"locationbar should be visible on default window.open()");
|
||||
ok(toolbars.menubar,
|
||||
"menubar be visible on default window.open()");
|
||||
ok(toolbars.personalbar,
|
||||
"personalbar should be visible on default window.open()");
|
||||
ok(toolbars.statusbar,
|
||||
"statusbar should be visible on default window.open()");
|
||||
ok(toolbars.toolbar,
|
||||
"toolbar should be visible on default window.open()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with non default parameters
|
||||
* on the content context.
|
||||
*
|
||||
* Ensure that locationbar can't be hidden in the content context, see bug#337344.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testNonDefaultContentToolbars(toolbars) {
|
||||
// Locationbar should always be visible on content context
|
||||
ok(toolbars.locationbar,
|
||||
"locationbar should be visible even with location=no");
|
||||
ok(!toolbars.menubar,
|
||||
"menubar shouldn't be visible when menubar=no");
|
||||
ok(!toolbars.personalbar,
|
||||
"personalbar shouldn't be visible when personalbar=no");
|
||||
// statusbar will report visible=true even when it's hidden because of bug#55820
|
||||
todo(!toolbars.statusbar,
|
||||
"statusbar shouldn't be visible when status=no");
|
||||
ok(!toolbars.toolbar,
|
||||
"toolbar shouldn't be visible when toolbar=no");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests toolbar visibility when opening a window with non default parameters
|
||||
* on the chrome context.
|
||||
*
|
||||
* @param toolbars
|
||||
* the visibility state of the toolbar elements
|
||||
*/
|
||||
function testNonDefaultChromeToolbars(toolbars) {
|
||||
// None of the toolbars should be visible if hidden with chrome privileges
|
||||
ok(!toolbars.locationbar,
|
||||
"locationbar should be visible on default window.open()");
|
||||
ok(!toolbars.menubar,
|
||||
"menubar be visible on default window.open()");
|
||||
ok(!toolbars.personalbar,
|
||||
"personalbar should be visible on default window.open()");
|
||||
ok(!toolbars.statusbar,
|
||||
"statusbar should be visible on default window.open()");
|
||||
ok(!toolbars.toolbar,
|
||||
"toolbar should be visible on default window.open()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that toolbars of a window opened in the content context have the
|
||||
* correct visibility.
|
||||
*
|
||||
* A window opened with default parameters should have all toolbars visible.
|
||||
*
|
||||
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
|
||||
* menubar=no, status=no", should only have location visible.
|
||||
*/
|
||||
add_task(function*() {
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: CONTENT_PAGE,
|
||||
}, function*(browser) {
|
||||
// First, call the default window.open() which will open a new tab
|
||||
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenDefault", {}, browser);
|
||||
let tab = yield newTabPromise;
|
||||
|
||||
// Check that all toolbars are visible
|
||||
let toolbars = yield getToolbarsFromBrowserContent(gBrowser.selectedBrowser);
|
||||
testDefaultToolbars(toolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
|
||||
// Now let's open a window with toolbars hidden
|
||||
let winPromise = BrowserTestUtils.waitForNewWindow();
|
||||
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenNonDefault", {}, browser);
|
||||
let popupWindow = yield winPromise;
|
||||
|
||||
let popupBrowser = popupWindow.gBrowser.selectedBrowser;
|
||||
yield BrowserTestUtils.browserLoaded(popupBrowser);
|
||||
|
||||
// Test toolbars visibility
|
||||
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
|
||||
testNonDefaultContentToolbars(popupToolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.closeWindow(popupWindow);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Ensure that toolbars of a window opened in the chrome context have the
|
||||
* correct visibility.
|
||||
*
|
||||
* A window opened with default parameters should have all toolbars visible.
|
||||
*
|
||||
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
|
||||
* menubar=no, status=no", should not have any toolbar visible.
|
||||
*/
|
||||
add_task(function* () {
|
||||
// First open a default window from this chrome context
|
||||
let defaultWindowPromise = BrowserTestUtils.waitForNewWindow();
|
||||
window.open("about:robots", "_blank");
|
||||
let defaultWindow = yield defaultWindowPromise;
|
||||
|
||||
// Check that all toolbars are visible
|
||||
let toolbars = getToolbarsFromWindowChrome(defaultWindow);
|
||||
testDefaultToolbars(toolbars);
|
||||
|
||||
// Now lets open a window with toolbars hidden from this chrome context
|
||||
let features = "location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no";
|
||||
let popupWindowPromise = BrowserTestUtils.waitForNewWindow();
|
||||
window.open("about:robots", "_blank", features);
|
||||
let popupWindow = yield popupWindowPromise;
|
||||
|
||||
// Test none of the tooolbars are visible
|
||||
let hiddenToolbars = getToolbarsFromWindowChrome(popupWindow);
|
||||
testNonDefaultChromeToolbars(hiddenToolbars);
|
||||
|
||||
// Cleanup
|
||||
yield BrowserTestUtils.closeWindow(defaultWindow);
|
||||
yield BrowserTestUtils.closeWindow(popupWindow);
|
||||
});
|
@ -5,7 +5,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p>
|
||||
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
|
||||
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
|
||||
<p><a id="winOpenDialog" href="#" onclick="return openWindow('dialog=yes');">Open a new window via window.open with dialog=1.</a></p>
|
||||
<p><a id="targetBlank" href="about:robots" target="_blank">Open a new window via target="_blank".</a></p>
|
||||
</body>
|
||||
@ -16,4 +16,4 @@ function openWindow(aFeatures="") {
|
||||
window.open("about:robots", "_blank", aFeatures);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -1526,7 +1526,7 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
rv = aScriptURI->GetSpec(spec);
|
||||
rv = aScriptURI->GetSpecIgnoringRef(spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -134,7 +134,12 @@ enum class LogReason : int {
|
||||
// Start. Do not insert, always add at end. If you remove items,
|
||||
// make sure the other items retain their values.
|
||||
D3D11InvalidCallDeviceRemoved = 0,
|
||||
D3D11InvalidCall = 1,
|
||||
D3D11InvalidCall,
|
||||
D3DLockTimeout,
|
||||
D3D10FinalizeFrame,
|
||||
D3D11FinalizeFrame,
|
||||
D3D10SyncLock,
|
||||
D3D11SyncLock,
|
||||
// End
|
||||
MustBeLessThanThis = 101,
|
||||
};
|
||||
@ -565,7 +570,7 @@ typedef Log<LOG_CRITICAL, CriticalLogger> CriticalLog;
|
||||
//
|
||||
// You should create a (new) enum in the LogReason and use it for the reason
|
||||
// parameter to ensure uniqueness.
|
||||
#define gfxDevCrash(reason) gfxCriticalError(int(LogOptions::AutoPrefix) | int(LogOptions::AssertOnCall) | int(LogOptions::CrashAction), (reason))
|
||||
#define gfxDevCrash(reason) gfxCriticalError(int(gfx::LogOptions::AutoPrefix) | int(gfx::LogOptions::AssertOnCall) | int(gfx::LogOptions::CrashAction), (reason))
|
||||
|
||||
// See nsDebug.h and the NS_WARN_IF macro
|
||||
|
||||
|
@ -650,12 +650,11 @@ CairoImage::GetTextureClient(CompositableClient *aClient)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
|
||||
TextureClientAutoLock autoLock(textureClient, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TextureClientAutoUnlock autoUnlock(textureClient);
|
||||
|
||||
textureClient->UpdateFromSurface(surface);
|
||||
|
||||
textureClient->SyncWithObject(forwarder->GetSyncObject());
|
||||
|
@ -98,22 +98,20 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
bufferCreated = true;
|
||||
}
|
||||
|
||||
if (!mBuffer->Lock(OpenMode::OPEN_WRITE_ONLY)) {
|
||||
mBuffer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
bool updated = false;
|
||||
{
|
||||
// Restrict drawTarget to a scope so that terminates before Unlock.
|
||||
RefPtr<DrawTarget> target =
|
||||
mBuffer->BorrowDrawTarget();
|
||||
TextureClientAutoLock autoLock(mBuffer, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
mBuffer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> target = mBuffer->BorrowDrawTarget();
|
||||
if (target) {
|
||||
aLayer->UpdateTarget(target);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
mBuffer->Unlock();
|
||||
|
||||
if (bufferCreated && !AddTextureClient(mBuffer)) {
|
||||
mBuffer = nullptr;
|
||||
@ -286,7 +284,9 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
||||
return nullptr;
|
||||
|
||||
// With a texClient, we can lock for writing.
|
||||
MOZ_ALWAYS_TRUE( texClient->Lock(OpenMode::OPEN_WRITE) );
|
||||
TextureClientAutoLock autoLock(texClient, OpenMode::OPEN_WRITE);
|
||||
DebugOnly<bool> succeeded = autoLock.Succeeded();
|
||||
MOZ_ASSERT(succeeded, "texture should have locked");
|
||||
|
||||
uint8_t* lockedBytes = texClient->GetLockedData();
|
||||
|
||||
@ -318,8 +318,6 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
||||
|
||||
texClient->RemoveFlags(TextureFlags::RB_SWAPPED);
|
||||
}
|
||||
|
||||
texClient->Unlock();
|
||||
}
|
||||
|
||||
return texClient.forget();
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "gfxUtils.h" // for gfxUtils
|
||||
#include "ipc/ShadowLayers.h" // for ShadowLayerForwarder
|
||||
#include "mozilla/ArrayUtils.h" // for ArrayLength
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget, Factory
|
||||
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
@ -570,33 +571,30 @@ ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
|
||||
|
||||
// We need to ensure that we lock these two buffers in the same
|
||||
// order as the compositor to prevent deadlocks.
|
||||
if (!mFrontClient->Lock(OpenMode::OPEN_READ_ONLY)) {
|
||||
TextureClientAutoLock frontLock(mFrontClient, OpenMode::OPEN_READ_ONLY);
|
||||
if (!frontLock.Succeeded()) {
|
||||
return;
|
||||
}
|
||||
if (mFrontClientOnWhite &&
|
||||
!mFrontClientOnWhite->Lock(OpenMode::OPEN_READ_ONLY)) {
|
||||
mFrontClient->Unlock();
|
||||
return;
|
||||
}
|
||||
{
|
||||
// Restrict the DrawTargets and frontBuffer to a scope to make
|
||||
// sure there is no more external references to the DrawTargets
|
||||
// when we Unlock the TextureClients.
|
||||
RefPtr<SourceSurface> surf = mFrontClient->BorrowDrawTarget()->Snapshot();
|
||||
RefPtr<SourceSurface> surfOnWhite = mFrontClientOnWhite
|
||||
? mFrontClientOnWhite->BorrowDrawTarget()->Snapshot()
|
||||
: nullptr;
|
||||
SourceRotatedBuffer frontBuffer(surf,
|
||||
surfOnWhite,
|
||||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
Maybe<TextureClientAutoLock> frontOnWhiteLock;
|
||||
if (mFrontClientOnWhite) {
|
||||
frontOnWhiteLock.emplace(mFrontClientOnWhite, OpenMode::OPEN_READ_ONLY);
|
||||
if (!frontOnWhiteLock->Succeeded()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mFrontClient->Unlock();
|
||||
if (mFrontClientOnWhite) {
|
||||
mFrontClientOnWhite->Unlock();
|
||||
}
|
||||
// Restrict the DrawTargets and frontBuffer to a scope to make
|
||||
// sure there is no more external references to the DrawTargets
|
||||
// when we Unlock the TextureClients.
|
||||
RefPtr<SourceSurface> surf = mFrontClient->BorrowDrawTarget()->Snapshot();
|
||||
RefPtr<SourceSurface> surfOnWhite = mFrontClientOnWhite
|
||||
? mFrontClientOnWhite->BorrowDrawTarget()->Snapshot()
|
||||
: nullptr;
|
||||
SourceRotatedBuffer frontBuffer(surf,
|
||||
surfOnWhite,
|
||||
mFrontBufferRect,
|
||||
mFrontBufferRotation);
|
||||
UpdateDestinationFrom(frontBuffer, updateRegion);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -185,17 +185,20 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
||||
data->mYSize, data->mCbCrSize, data->mStereoMode,
|
||||
TextureFlags::DEFAULT | mTextureFlags
|
||||
);
|
||||
if (!texture || !texture->Lock(OpenMode::OPEN_WRITE_ONLY)) {
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool status = texture->AsTextureClientYCbCr()->UpdateYCbCr(*data);
|
||||
MOZ_ASSERT(status);
|
||||
|
||||
texture->Unlock();
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE ||
|
||||
image->GetFormat() == ImageFormat::EGLIMAGE) {
|
||||
gfx::IntSize size = image->GetSize();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "ImageTypes.h" // for StereoMode
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
@ -720,17 +721,39 @@ protected:
|
||||
size_t mBufSize;
|
||||
};
|
||||
|
||||
struct TextureClientAutoUnlock
|
||||
// Automatically lock and unlock a texture. Since texture locking is fallible,
|
||||
// Succeeded() must be checked on the guard object before proceeding.
|
||||
class MOZ_RAII TextureClientAutoLock
|
||||
{
|
||||
TextureClient* mTexture;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
|
||||
|
||||
explicit TextureClientAutoUnlock(TextureClient* aTexture)
|
||||
: mTexture(aTexture) {}
|
||||
|
||||
~TextureClientAutoUnlock()
|
||||
public:
|
||||
TextureClientAutoLock(TextureClient* aTexture, OpenMode aMode
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mTexture(aTexture),
|
||||
mSucceeded(false)
|
||||
{
|
||||
mTexture->Unlock();
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
mSucceeded = mTexture->Lock(aMode);
|
||||
mChecked = false;
|
||||
}
|
||||
~TextureClientAutoLock() {
|
||||
MOZ_ASSERT(mChecked);
|
||||
if (mSucceeded) {
|
||||
mTexture->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool Succeeded() {
|
||||
mChecked = true;
|
||||
return mSucceeded;
|
||||
}
|
||||
|
||||
private:
|
||||
TextureClient* mTexture;
|
||||
DebugOnly<bool> mChecked;
|
||||
bool mSucceeded;
|
||||
};
|
||||
|
||||
class KeepAlive
|
||||
|
@ -601,7 +601,8 @@ CopyFrontToBack(TextureClient* aFront,
|
||||
TextureClient* aBack,
|
||||
const gfx::IntRect& aRectToCopy)
|
||||
{
|
||||
if (!aFront->Lock(OpenMode::OPEN_READ)) {
|
||||
TextureClientAutoLock frontLock(aFront, OpenMode::OPEN_READ);
|
||||
if (!frontLock.Succeeded()) {
|
||||
gfxCriticalError() << "[Tiling:Client] Failed to lock the tile's front buffer";
|
||||
return false;
|
||||
}
|
||||
@ -613,8 +614,6 @@ CopyFrontToBack(TextureClient* aFront,
|
||||
|
||||
gfx::IntPoint rectToCopyTopLeft = aRectToCopy.TopLeft();
|
||||
aFront->CopyToTextureClient(aBack, &aRectToCopy, &rectToCopyTopLeft);
|
||||
|
||||
aFront->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ static bool LockD3DTexture(T* aTexture)
|
||||
if (mutex) {
|
||||
HRESULT hr = mutex->AcquireSync(0, 10000);
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
MOZ_CRASH();
|
||||
gfxDevCrash(LogReason::D3DLockTimeout) << "D3D lock mutex timeout";
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
@ -1245,7 +1245,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_CRASH();
|
||||
gfxDevCrash(LogReason::D3D10FinalizeFrame) << "Without device reset: " << hexa(hr);
|
||||
}
|
||||
|
||||
// test QI
|
||||
@ -1253,8 +1253,10 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
hr = mD3D10Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
|
||||
|
||||
if (FAILED(hr) || !mutex) {
|
||||
// Leave both the critical error and MOZ_CRASH for now; the critical error lets
|
||||
// us "save" the hr value. We will probably eventuall replace this with gfxDevCrash.
|
||||
gfxCriticalError() << "Failed to get KeyedMutex: " << hexa(hr);
|
||||
MOZ_CRASH();
|
||||
MOZ_CRASH("GFX: Cannot get D3D10 KeyedMutex");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1270,7 +1272,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_CRASH();
|
||||
gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
|
||||
}
|
||||
|
||||
// test QI
|
||||
@ -1278,8 +1280,10 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
hr = mD3D11Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
|
||||
|
||||
if (FAILED(hr) || !mutex) {
|
||||
// Leave both the critical error and MOZ_CRASH for now; the critical error lets
|
||||
// us "save" the hr value. We will probably eventuall replace this with gfxDevCrash.
|
||||
gfxCriticalError() << "Failed to get KeyedMutex: " << hexa(hr);
|
||||
MOZ_CRASH();
|
||||
MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1293,7 +1297,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
gfxWarning() << "AcquireSync timed out because of device reset.";
|
||||
return;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
gfxDevCrash(LogReason::D3D10SyncLock) << "Timeout on the D3D10 sync lock";
|
||||
}
|
||||
|
||||
D3D10_BOX box;
|
||||
@ -1321,7 +1325,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
gfxWarning() << "AcquireSync timed out because of device reset.";
|
||||
return;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
|
||||
}
|
||||
|
||||
D3D11_BOX box;
|
||||
@ -1334,7 +1338,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
return;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
MOZ_CRASH("GFX: Invalid D3D11 content device");
|
||||
}
|
||||
|
||||
RefPtr<ID3D11DeviceContext> ctx;
|
||||
|
@ -90,11 +90,13 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
|
||||
if (!mTextureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
|
||||
|
||||
TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
MOZ_ASSERT(false, "Failed to lock the texture.");
|
||||
return false;
|
||||
}
|
||||
TextureClientAutoUnlock unlock(mTextureClient);
|
||||
|
||||
if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
|
||||
MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
|
||||
return false;
|
||||
|
@ -51,11 +51,21 @@ inline Point ToPoint(const gfxPoint &aPoint)
|
||||
return Point(Float(aPoint.x), Float(aPoint.y));
|
||||
}
|
||||
|
||||
inline Size ToSize(const gfxSize &aSize)
|
||||
{
|
||||
return Size(Float(aSize.width), Float(aSize.height));
|
||||
}
|
||||
|
||||
inline gfxPoint ThebesPoint(const Point &aPoint)
|
||||
{
|
||||
return gfxPoint(aPoint.x, aPoint.y);
|
||||
}
|
||||
|
||||
inline gfxSize ThebesSize(const Size &aSize)
|
||||
{
|
||||
return gfxSize(aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
inline gfxRect ThebesRect(const Rect &aRect)
|
||||
{
|
||||
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
|
@ -847,6 +847,7 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
||||
// add font entries for each of the faces
|
||||
uint32_t numFonts = mFontPatterns.Length();
|
||||
NS_ASSERTION(numFonts, "font family containing no faces!!");
|
||||
uint32_t numRegularFaces = 0;
|
||||
for (uint32_t i = 0; i < numFonts; i++) {
|
||||
FcPattern* face = mFontPatterns[i];
|
||||
|
||||
@ -859,6 +860,12 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
||||
new gfxFontconfigFontEntry(faceName, face);
|
||||
AddFontEntry(fontEntry);
|
||||
|
||||
if (fontEntry->IsUpright() &&
|
||||
fontEntry->Weight() == NS_FONT_WEIGHT_NORMAL &&
|
||||
fontEntry->Stretch() == NS_FONT_STRETCH_NORMAL) {
|
||||
numRegularFaces++;
|
||||
}
|
||||
|
||||
if (LOG_FONTLIST_ENABLED()) {
|
||||
LOG_FONTLIST(("(fontlist) added (%s) to family (%s)"
|
||||
" with style: %s weight: %d stretch: %d"
|
||||
@ -872,6 +879,12 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
||||
NS_ConvertUTF16toUTF8(fullname).get()));
|
||||
}
|
||||
}
|
||||
|
||||
// somewhat arbitrary, but define a family with two or more regular
|
||||
// faces as a family for which intra-family fallback should be used
|
||||
if (numRegularFaces > 1) {
|
||||
mCheckForFallbackFaces = true;
|
||||
}
|
||||
mFaceNamesInitialized = true;
|
||||
mFontPatterns.Clear();
|
||||
SetHasStyles(true);
|
||||
|
@ -663,7 +663,8 @@ public:
|
||||
mIsSimpleFamily(false),
|
||||
mIsBadUnderlineFamily(false),
|
||||
mFamilyCharacterMapInitialized(false),
|
||||
mSkipDefaultFeatureSpaceCheck(false)
|
||||
mSkipDefaultFeatureSpaceCheck(false),
|
||||
mCheckForFallbackFaces(false)
|
||||
{ }
|
||||
|
||||
const nsString& Name() { return mName; }
|
||||
@ -767,6 +768,7 @@ public:
|
||||
}
|
||||
|
||||
bool IsBadUnderlineFamily() const { return mIsBadUnderlineFamily; }
|
||||
bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
|
||||
|
||||
// sort available fonts to put preferred (standard) faces towards the end
|
||||
void SortAvailableFonts();
|
||||
@ -822,6 +824,7 @@ protected:
|
||||
bool mIsBadUnderlineFamily : 1;
|
||||
bool mFamilyCharacterMapInitialized : 1;
|
||||
bool mSkipDefaultFeatureSpaceCheck : 1;
|
||||
bool mCheckForFallbackFaces : 1; // check other faces for character
|
||||
|
||||
enum {
|
||||
// for "simple" families, the faces are stored in mAvailableFonts
|
||||
|
@ -1648,6 +1648,12 @@ gfxFontGroup::AddFamilyToFontList(gfxFontFamily* aFamily)
|
||||
mFonts.AppendElement(ff);
|
||||
}
|
||||
}
|
||||
// for a family marked as "check fallback faces", only mark the last
|
||||
// entry so that fallbacks for a family are only checked once
|
||||
if (aFamily->CheckForFallbackFaces() &&
|
||||
!fontEntryList.IsEmpty() && !mFonts.IsEmpty()) {
|
||||
mFonts.LastElement().SetCheckForFallbackFaces();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2555,6 +2561,23 @@ gfxFontGroup::FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFont>
|
||||
gfxFontGroup::FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh,
|
||||
int32_t aRunScript)
|
||||
{
|
||||
GlobalFontMatch data(aCh, aRunScript, &mStyle);
|
||||
aFamily->SearchAllFontsForChar(&data);
|
||||
gfxFontEntry* fe = data.mBestMatch;
|
||||
if (!fe) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool needsBold = mStyle.weight >= 600 && !fe->IsBold() &&
|
||||
mStyle.allowSyntheticWeight;
|
||||
RefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
gfxFontGroup::GetUnderlineOffset()
|
||||
{
|
||||
@ -2619,10 +2642,17 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
||||
return firstFont.forget();
|
||||
}
|
||||
|
||||
// If italic, test the regular face to see if it supports character.
|
||||
// Only do this for platform fonts, not userfonts.
|
||||
if (mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
!firstFont->GetFontEntry()->IsUserFont()) {
|
||||
if (mFonts[0].CheckForFallbackFaces()) {
|
||||
RefPtr<gfxFont> font =
|
||||
FindFallbackFaceForChar(mFonts[0].Family(), aCh, aRunScript);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
} else if (mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
!firstFont->GetFontEntry()->IsUserFont()) {
|
||||
// If italic, test the regular face to see if it supports
|
||||
// character. Only do this for platform fonts, not userfonts.
|
||||
RefPtr<gfxFont> font =
|
||||
FindNonItalicFaceForChar(mFonts[0].Family(), aCh);
|
||||
if (font) {
|
||||
@ -2722,17 +2752,30 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
||||
}
|
||||
}
|
||||
|
||||
// If italic, test the regular face to see if it supports the character.
|
||||
// Only do this for platform fonts, not userfonts.
|
||||
fe = ff.FontEntry();
|
||||
if (mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
!fe->mIsUserFontContainer &&
|
||||
!fe->IsUserFont()) {
|
||||
font = FindNonItalicFaceForChar(ff.Family(), aCh);
|
||||
// check other family faces if needed
|
||||
if (ff.CheckForFallbackFaces()) {
|
||||
NS_ASSERTION(i == 0 ? true :
|
||||
!mFonts[i-1].CheckForFallbackFaces() ||
|
||||
!mFonts[i-1].Family()->Name().Equals(ff.Family()->Name()),
|
||||
"should only do fallback once per font family");
|
||||
font = FindFallbackFaceForChar(ff.Family(), aCh, aRunScript);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
} else {
|
||||
// If italic, test the regular face to see if it supports the
|
||||
// character. Only do this for platform fonts, not userfonts.
|
||||
fe = ff.FontEntry();
|
||||
if (mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
!fe->mIsUserFontContainer &&
|
||||
!fe->IsUserFont()) {
|
||||
font = FindNonItalicFaceForChar(ff.Family(), aCh);
|
||||
if (font) {
|
||||
*aMatchType = gfxTextRange::kFontGroup;
|
||||
return font.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,12 +882,13 @@ protected:
|
||||
public:
|
||||
FamilyFace() : mFamily(nullptr), mFontEntry(nullptr),
|
||||
mNeedsBold(false), mFontCreated(false),
|
||||
mLoading(false), mInvalid(false)
|
||||
mLoading(false), mInvalid(false),
|
||||
mCheckForFallbackFaces(false)
|
||||
{ }
|
||||
|
||||
FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont)
|
||||
: mFamily(aFamily), mNeedsBold(false), mFontCreated(true),
|
||||
mLoading(false), mInvalid(false)
|
||||
mLoading(false), mInvalid(false), mCheckForFallbackFaces(false)
|
||||
{
|
||||
NS_ASSERTION(aFont, "font pointer must not be null");
|
||||
NS_ASSERTION(!aFamily ||
|
||||
@ -900,7 +901,7 @@ protected:
|
||||
FamilyFace(gfxFontFamily* aFamily, gfxFontEntry* aFontEntry,
|
||||
bool aNeedsBold)
|
||||
: mFamily(aFamily), mNeedsBold(aNeedsBold), mFontCreated(false),
|
||||
mLoading(false), mInvalid(false)
|
||||
mLoading(false), mInvalid(false), mCheckForFallbackFaces(false)
|
||||
{
|
||||
NS_ASSERTION(aFontEntry, "font entry pointer must not be null");
|
||||
NS_ASSERTION(!aFamily ||
|
||||
@ -915,7 +916,8 @@ protected:
|
||||
mNeedsBold(aOtherFamilyFace.mNeedsBold),
|
||||
mFontCreated(aOtherFamilyFace.mFontCreated),
|
||||
mLoading(aOtherFamilyFace.mLoading),
|
||||
mInvalid(aOtherFamilyFace.mInvalid)
|
||||
mInvalid(aOtherFamilyFace.mInvalid),
|
||||
mCheckForFallbackFaces(aOtherFamilyFace.mCheckForFallbackFaces)
|
||||
{
|
||||
if (mFontCreated) {
|
||||
mFont = aOtherFamilyFace.mFont;
|
||||
@ -978,6 +980,8 @@ protected:
|
||||
void CheckState(bool& aSkipDrawing);
|
||||
void SetLoading(bool aIsLoading) { mLoading = aIsLoading; }
|
||||
void SetInvalid() { mInvalid = true; }
|
||||
bool CheckForFallbackFaces() const { return mCheckForFallbackFaces; }
|
||||
void SetCheckForFallbackFaces() { mCheckForFallbackFaces = true; }
|
||||
|
||||
void SetFont(gfxFont* aFont)
|
||||
{
|
||||
@ -1006,6 +1010,7 @@ protected:
|
||||
bool mFontCreated : 1;
|
||||
bool mLoading : 1;
|
||||
bool mInvalid : 1;
|
||||
bool mCheckForFallbackFaces : 1;
|
||||
};
|
||||
|
||||
// List of font families, either named or generic.
|
||||
@ -1102,7 +1107,13 @@ protected:
|
||||
already_AddRefed<gfxFont>
|
||||
FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh);
|
||||
|
||||
// helper methods for looking up fonts
|
||||
// search all faces in a family for a fallback in cases where it's unclear
|
||||
// whether the family might have a font for a given character
|
||||
already_AddRefed<gfxFont>
|
||||
FindFallbackFaceForChar(gfxFontFamily* aFamily, uint32_t aCh,
|
||||
int32_t aRunScript);
|
||||
|
||||
// helper methods for looking up fonts
|
||||
|
||||
// lookup and add a font with a given name (i.e. *not* a generic!)
|
||||
void AddPlatformFont(const nsAString& aName,
|
||||
|
@ -1,40 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
OS_CXXFLAGS := $(filter-out -fshort-wchar,$(OS_CXXFLAGS))
|
||||
|
||||
ACDEFINES =
|
||||
|
||||
ifndef MOZ_NATIVE_LIBEVENT # {
|
||||
vpath %.c \
|
||||
$(srcdir)/src/third_party/libevent \
|
||||
$(NULL)
|
||||
endif # }
|
||||
|
||||
vpath %.cc \
|
||||
$(srcdir)/src/base \
|
||||
$(srcdir)/src/chrome/common \
|
||||
$(NULL)
|
||||
|
||||
vpath %.mm \
|
||||
$(srcdir)/src/base \
|
||||
$(srcdir)/src/chrome/common \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(TK_CFLAGS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef MOZ_NATIVE_LIBEVENT # {
|
||||
|
||||
export-preqs = \
|
||||
$(call mkdir_deps,$(CURDIR)/third_party/libevent) \
|
||||
$(NULL)
|
||||
|
||||
export:: $(DIST)/third_party/libevent/event.h
|
||||
|
||||
$(DIST)/third_party/libevent/event.h:: $(export-preqs)
|
||||
echo '#include <event.h>' > $(CURDIR)/third_party/libevent/event.h
|
||||
|
||||
endif # }
|
@ -167,6 +167,8 @@ if '86' not in ost and 'arm' not in ost and 'mips' not in ost:
|
||||
'src/base/atomicops_internals_mutex.cc',
|
||||
]
|
||||
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "base/scoped_nsautorelease_pool.h"
|
||||
#include "base/time.h"
|
||||
#include "nsDependentSubstring.h"
|
||||
#include "third_party/libevent/event.h"
|
||||
#include "event.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
// This macro checks that the _EVENT_SIZEOF_* constants defined in
|
||||
|
@ -1 +0,0 @@
|
||||
%/SharedMemoryBasic_mach.cpp: ;
|
@ -123,7 +123,7 @@ TraceGenericPointerRoot(JSTracer* trc, gc::Cell** thingp, const char* name);
|
||||
void
|
||||
TraceManuallyBarrieredGenericPointerEdge(JSTracer* trc, gc::Cell** thingp, const char* name);
|
||||
|
||||
// Depricated. Please use one of the strongly typed variants above.
|
||||
// Deprecated. Please use one of the strongly typed variants above.
|
||||
void
|
||||
TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind);
|
||||
|
||||
|
@ -813,7 +813,7 @@ IonBuilder::build()
|
||||
script()->filename(), script()->lineno(), (void*)script(),
|
||||
AnalysisModeString(info().analysisMode()));
|
||||
} else {
|
||||
JitSpew(JitSpew_IonScripts, "%sompiling script %s:%" PRIuSIZE " (%p) (warmup-counter=%" PRIuSIZE ", level=%s)",
|
||||
JitSpew(JitSpew_IonScripts, "%sompiling script %s:%" PRIuSIZE " (%p) (warmup-counter=%" PRIu32 ", level=%s)",
|
||||
(script()->hasIonScript() ? "Rec" : "C"),
|
||||
script()->filename(), script()->lineno(), (void*)script(),
|
||||
script()->getWarmUpCount(), OptimizationLevelString(optimizationInfo().level()));
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define jit_JitSpewer_h
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -76,7 +76,7 @@ struct ArgumentsData
|
||||
// Maximum supported value of arguments.length. This bounds the maximum
|
||||
// number of arguments that can be supplied to Function.prototype.apply.
|
||||
// This value also bounds the number of elements parsed in an array
|
||||
// initialiser.
|
||||
// initializer.
|
||||
static const unsigned ARGS_LENGTH_MAX = 500 * 1000;
|
||||
|
||||
/*
|
||||
|
@ -166,12 +166,12 @@ struct ForOfPIC
|
||||
*
|
||||
* Array.prototype's slot number for @@iterator (arrayProtoIteratorSlot_)
|
||||
* Array.prototype's canonical value for @@iterator (canonicalIteratorFunc_)
|
||||
* To quickly retreive and ensure that the iterator constructor
|
||||
* To quickly retrieve and ensure that the iterator constructor
|
||||
* stored in the slot has not changed.
|
||||
*
|
||||
* ArrayIterator.prototype's slot number for 'next' (arrayIteratorProtoNextSlot_)
|
||||
* ArrayIterator.prototype's canonical value for 'next' (canonicalNextFunc_)
|
||||
* To quickly retreive and ensure that the 'next' method for ArrayIterator
|
||||
* To quickly retrieve and ensure that the 'next' method for ArrayIterator
|
||||
* objects has not changed.
|
||||
*/
|
||||
class Chain : public BaseChain
|
||||
|
@ -617,7 +617,7 @@ JSRuntime::resetJitStackLimit()
|
||||
{
|
||||
// Note that, for now, we use the untrusted limit for ion. This is fine,
|
||||
// because it's the most conservative limit, and if we hit it, we'll bail
|
||||
// out of ion into the interpeter, which will do a proper recursion check.
|
||||
// out of ion into the interpreter, which will do a proper recursion check.
|
||||
#ifdef JS_SIMULATOR
|
||||
jitStackLimit_ = jit::Simulator::StackLimit();
|
||||
#else
|
||||
|
@ -1032,7 +1032,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
/* Garbage collector state, used by jsgc.c. */
|
||||
js::gc::GCRuntime gc;
|
||||
|
||||
/* Garbage collector state has been sucessfully initialized. */
|
||||
/* Garbage collector state has been successfully initialized. */
|
||||
bool gcInitialized;
|
||||
|
||||
int gcZeal() { return gc.zeal(); }
|
||||
@ -1102,7 +1102,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
/* Had an out-of-memory error which did not populate an exception. */
|
||||
bool hadOutOfMemory;
|
||||
|
||||
/* We are curently deleting an object due to an initialization failure. */
|
||||
/* We are currently deleting an object due to an initialization failure. */
|
||||
mozilla::DebugOnly<bool> handlingInitFailure;
|
||||
|
||||
/* A context has been created on this runtime. */
|
||||
|
@ -685,21 +685,25 @@ TraceLoggerThreadState::init()
|
||||
enabledTextIds[TraceLogger_FoldTests] = true;
|
||||
enabledTextIds[TraceLogger_SplitCriticalEdges] = true;
|
||||
enabledTextIds[TraceLogger_RenumberBlocks] = true;
|
||||
enabledTextIds[TraceLogger_ScalarReplacement] = true;
|
||||
enabledTextIds[TraceLogger_DominatorTree] = true;
|
||||
enabledTextIds[TraceLogger_PhiAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_ScalarReplacement] = true;
|
||||
enabledTextIds[TraceLogger_MakeLoopsContiguous] = true;
|
||||
enabledTextIds[TraceLogger_ApplyTypes] = true;
|
||||
enabledTextIds[TraceLogger_EagerSimdUnbox] = true;
|
||||
enabledTextIds[TraceLogger_AliasAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_GVN] = true;
|
||||
enabledTextIds[TraceLogger_LICM] = true;
|
||||
enabledTextIds[TraceLogger_Sincos] = true;
|
||||
enabledTextIds[TraceLogger_RangeAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_LoopUnrolling] = true;
|
||||
enabledTextIds[TraceLogger_EffectiveAddressAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_AlignmentMaskAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_EliminateDeadCode] = true;
|
||||
enabledTextIds[TraceLogger_ReorderInstructions] = true;
|
||||
enabledTextIds[TraceLogger_EdgeCaseAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_EliminateRedundantChecks] = true;
|
||||
enabledTextIds[TraceLogger_AddKeepAliveInstructions] = true;
|
||||
enabledTextIds[TraceLogger_GenerateLIR] = true;
|
||||
enabledTextIds[TraceLogger_RegisterAllocation] = true;
|
||||
enabledTextIds[TraceLogger_GenerateCode] = true;
|
||||
|
@ -35,7 +35,7 @@ namespace jit {
|
||||
/*
|
||||
* Tracelogging overview.
|
||||
*
|
||||
* Tracelogging makes it possible to trace the occurence of a single event and/or
|
||||
* Tracelogging makes it possible to trace the occurrence of a single event and/or
|
||||
* the start and stop of an event. This is implemented to give an as low overhead as
|
||||
* possible so it doesn't interfere with running.
|
||||
*
|
||||
@ -47,17 +47,17 @@ namespace jit {
|
||||
*
|
||||
* 2) Optionally create a TraceLoggerEvent for the text that needs to get logged. This
|
||||
* step takes some time, so try to do this beforehand, outside the hot
|
||||
* path and don't do unnecessary repetitions, since it will criple
|
||||
* path and don't do unnecessary repetitions, since it will cripple
|
||||
* performance.
|
||||
* - TraceLoggerEvent event(logger, "foo");
|
||||
*
|
||||
* There are also some predefined events. They are located in
|
||||
* TraceLoggerTextId. They don't require to create an TraceLoggerEvent and
|
||||
* can also be used as an argument to these functions.
|
||||
* 3) Log the occurence of a single event:
|
||||
* 3) Log the occurrence of a single event:
|
||||
* - TraceLogTimestamp(logger, TraceLoggerTextId);
|
||||
* Note: it is temporarily not supported to provide an TraceLoggerEvent as
|
||||
* argument to log the occurence of a single event.
|
||||
* argument to log the occurrence of a single event.
|
||||
*
|
||||
* or log the start and stop of an event:
|
||||
* - TraceLogStartEvent(logger, TraceLoggerTextId);
|
||||
|
@ -28,7 +28,7 @@
|
||||
* binary file.
|
||||
* - treeFormat: The format used to encode the tree. By default "64,64,31,1,32".
|
||||
* There are currently no other formats to save the tree.
|
||||
* - 64,64,31,1,31 signifies how many bytes are used for the different
|
||||
* - 64,64,31,1,32 signifies how many bytes are used for the different
|
||||
* parts of the tree.
|
||||
* => 64 bits: Time Stamp Counter of start of event.
|
||||
* => 64 bits: Time Stamp Counter of end of event.
|
||||
|
@ -1831,7 +1831,7 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
|
||||
* Actually ({}).toString.call(Uint8Array.prototype) should throw, because
|
||||
* Uint8Array.prototype lacks the the typed array internal slots. (Same as
|
||||
* with %TypedArray%.prototype.) It's not clear this is desirable (see
|
||||
* above), but it's what we've always done, so keep doing it til we
|
||||
* above), but it's what we've always done, so keep doing it till we
|
||||
* implement @@toStringTag or ES6 changes.
|
||||
*/ \
|
||||
#typedArray "Prototype", \
|
||||
|
@ -1061,7 +1061,7 @@ public:
|
||||
MOZ_ASSERT_IF(isAtRoot, mContainerReferenceFrame == mBuilder->RootReferenceFrame());
|
||||
mContainerAnimatedGeometryRoot = isAtRoot
|
||||
? mContainerReferenceFrame
|
||||
: nsLayoutUtils::GetAnimatedGeometryRootFor(aContainerItem, aBuilder);
|
||||
: aContainerItem->AnimatedGeometryRoot();
|
||||
MOZ_ASSERT(!mBuilder->IsPaintingToWindow() ||
|
||||
nsLayoutUtils::IsAncestorFrameCrossDoc(mBuilder->RootReferenceFrame(),
|
||||
mContainerAnimatedGeometryRoot));
|
||||
@ -3716,8 +3716,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
|
||||
|
||||
// Try using the actual active scrolled root of the backmost item, as that
|
||||
// should result in the least invalidation when scrolling.
|
||||
*aAnimatedGeometryRoot =
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder);
|
||||
*aAnimatedGeometryRoot = item->AnimatedGeometryRoot();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3892,8 +3891,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
bool forceInactive;
|
||||
const nsIFrame* animatedGeometryRoot;
|
||||
const nsIFrame* animatedGeometryRootForScrollMetadata = nullptr;
|
||||
const nsIFrame* realAnimatedGeometryRootOfItem =
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(item, mBuilder);
|
||||
const nsIFrame* realAnimatedGeometryRootOfItem = item->AnimatedGeometryRoot();
|
||||
if (mFlattenToSingleLayer) {
|
||||
forceInactive = true;
|
||||
animatedGeometryRoot = lastAnimatedGeometryRoot;
|
||||
|
@ -1996,11 +1996,17 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: mFrame(aFrame)
|
||||
, mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
|
||||
, mAnimatedGeometryRoot(nullptr)
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
, mPainted(false)
|
||||
#endif
|
||||
{
|
||||
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
|
||||
// This can return the wrong result if the item override ShouldFixToViewport(),
|
||||
// the item needs to set it again in its constructor.
|
||||
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForInit(this, aBuilder);
|
||||
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
|
||||
mAnimatedGeometryRoot), "Bad");
|
||||
NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
|
||||
!aBuilder->IsForPainting(), "dirty rect not set");
|
||||
// The dirty rect is for mCurrentFrame, so we have to use
|
||||
@ -2141,6 +2147,9 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
|
||||
|
||||
mBounds = GetBoundsInternal(aBuilder);
|
||||
mDestArea = GetDestAreaInternal(aBuilder);
|
||||
if (ShouldFixToViewport(aBuilder)) {
|
||||
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
nsRect
|
||||
@ -3786,8 +3795,7 @@ RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
|
||||
LayerState result = LAYER_INACTIVE;
|
||||
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
||||
if (result == LAYER_INACTIVE &&
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(i, aBuilder) !=
|
||||
aExpectedAnimatedGeometryRootForChildren) {
|
||||
i->AnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
|
||||
result = LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
@ -4061,8 +4069,7 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
if (NeedsActiveLayer(aBuilder))
|
||||
return LAYER_ACTIVE;
|
||||
|
||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList,
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder));
|
||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, AnimatedGeometryRoot());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -4794,6 +4801,7 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(outerFrame);
|
||||
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, outerFrame);
|
||||
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
|
||||
}
|
||||
|
||||
|
@ -1231,6 +1231,7 @@ public:
|
||||
: mFrame(aFrame)
|
||||
, mClip(nullptr)
|
||||
, mReferenceFrame(nullptr)
|
||||
, mAnimatedGeometryRoot(nullptr)
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
, mPainted(false)
|
||||
#endif
|
||||
@ -1692,6 +1693,11 @@ public:
|
||||
*/
|
||||
virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
|
||||
|
||||
nsIFrame* AnimatedGeometryRoot() const {
|
||||
MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
|
||||
return mAnimatedGeometryRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this display item (or any children) contains content that might
|
||||
* be rendered with component alpha (e.g. subpixel antialiasing). Returns the
|
||||
@ -1751,6 +1757,7 @@ protected:
|
||||
const DisplayItemClip* mClip;
|
||||
// Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
|
||||
const nsIFrame* mReferenceFrame;
|
||||
nsIFrame* mAnimatedGeometryRoot;
|
||||
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
|
||||
nsPoint mToReferenceFrame;
|
||||
// This is the rectangle that needs to be painted.
|
||||
|
@ -162,9 +162,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
||||
}
|
||||
bool snap;
|
||||
nsRect rect = aItem->GetBounds(aBuilder, &snap);
|
||||
nsRect layerRect = rect -
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(aItem, aBuilder)->
|
||||
GetOffsetToCrossDoc(aItem->ReferenceFrame());
|
||||
nsRect layerRect = rect - aItem->AnimatedGeometryRoot()->GetOffsetToCrossDoc(aItem->ReferenceFrame());
|
||||
nscolor color;
|
||||
nsRect vis = aItem->GetVisibleRect();
|
||||
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
|
||||
@ -179,7 +177,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
||||
aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
|
||||
}
|
||||
#endif
|
||||
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
|
||||
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s ref=0x%p agr=0x%p",
|
||||
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
|
||||
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
|
||||
rect.x, rect.y, rect.width, rect.height,
|
||||
@ -187,7 +185,8 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
||||
vis.x, vis.y, vis.width, vis.height,
|
||||
component.x, component.y, component.width, component.height,
|
||||
clip.ToString().get(),
|
||||
aItem->IsUniform(aBuilder, &color) ? " uniform" : "");
|
||||
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
|
||||
aItem->ReferenceFrame(), aItem->AnimatedGeometryRoot());
|
||||
|
||||
nsRegionRectIterator iter(opaque);
|
||||
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
|
||||
|
@ -1067,12 +1067,6 @@ GetDisplayPortFromMarginsData(nsIContent* aContent,
|
||||
}
|
||||
}
|
||||
|
||||
// Inflate the rectangle by 1 so that we always push to the next tile
|
||||
// boundary. This is desirable to stop from having a rectangle with a
|
||||
// moving origin occasionally being smaller when it coincidentally lines
|
||||
// up to tile boundaries.
|
||||
screenRect.Inflate(1);
|
||||
|
||||
ScreenPoint scrollPosScreen = LayoutDevicePoint::FromAppUnits(scrollPos, auPerDevPixel)
|
||||
* res;
|
||||
|
||||
@ -1961,6 +1955,25 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
|
||||
return GetAnimatedGeometryRootForFrame(aBuilder, f);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsLayoutUtils::GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
nsIFrame* f = aItem->Frame();
|
||||
if (aItem->ShouldFixToViewport(aBuilder)) {
|
||||
// Make its active scrolled root be the active scrolled root of
|
||||
// the enclosing viewport, since it shouldn't be scrolled by scrolled
|
||||
// frames in its document. InvalidateFixedBackgroundFramesFromList in
|
||||
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
|
||||
nsIFrame* viewportFrame =
|
||||
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
|
||||
if (viewportFrame) {
|
||||
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
|
||||
}
|
||||
}
|
||||
return GetAnimatedGeometryRootForFrame(aBuilder, f);
|
||||
}
|
||||
|
||||
// static
|
||||
nsIScrollableFrame*
|
||||
nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
|
||||
|
@ -563,6 +563,13 @@ public:
|
||||
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
uint32_t aFlags = 0);
|
||||
/**
|
||||
* Version of GetAnimatedGeometryRootFor that can be called in nsDisplayItem
|
||||
* constructor, and only from there. Not valid for transform items, but they
|
||||
* set their AGR in their constructor.
|
||||
*/
|
||||
static nsIFrame* GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
|
||||
/**
|
||||
* Finds the nearest ancestor frame to aFrame that is considered to have (or
|
||||
|
@ -239,7 +239,11 @@ public:
|
||||
nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
uint32_t aLayer, const nsStyleBackground* aBg)
|
||||
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBg)
|
||||
{}
|
||||
{
|
||||
if (ShouldFixToViewport(aBuilder)) {
|
||||
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
|
||||
|
||||
|
@ -4752,9 +4752,15 @@ ScrollFrameHelper::FinishReflowForScrollbar(nsIContent* aContent,
|
||||
bool
|
||||
ScrollFrameHelper::ReflowFinished()
|
||||
{
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPostedReflowCallback = false;
|
||||
|
||||
if (NS_SUBTREE_DIRTY(mOuter)) {
|
||||
// We will get another call after the next reflow and scrolling
|
||||
// later is less janky.
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
ScrollToRestoredPosition();
|
||||
|
||||
// Clamp current scroll position to new bounds. Normally this won't
|
||||
@ -4768,9 +4774,9 @@ ScrollFrameHelper::ReflowFinished()
|
||||
mDestination = GetScrollPosition();
|
||||
}
|
||||
|
||||
if (NS_SUBTREE_DIRTY(mOuter) || !mUpdateScrollbarAttributes)
|
||||
if (!mUpdateScrollbarAttributes) {
|
||||
return false;
|
||||
|
||||
}
|
||||
mUpdateScrollbarAttributes = false;
|
||||
|
||||
// Update scrollbar attributes.
|
||||
|
@ -102,7 +102,9 @@ MP4Metadata::MP4Metadata(Stream* aSource)
|
||||
mPrivate->mMetadataExtractor->flags() & MediaExtractor::CAN_SEEK;
|
||||
sp<MetaData> metaData = mPrivate->mMetadataExtractor->getMetaData();
|
||||
|
||||
UpdateCrypto(metaData.get());
|
||||
if (metaData.get()) {
|
||||
UpdateCrypto(metaData.get());
|
||||
}
|
||||
}
|
||||
|
||||
MP4Metadata::~MP4Metadata()
|
||||
@ -317,6 +319,9 @@ MP4Metadata::GetTrackNumber(mozilla::TrackID aTrackID)
|
||||
size_t numTracks = mPrivate->mMetadataExtractor->countTracks();
|
||||
for (size_t i = 0; i < numTracks; i++) {
|
||||
sp<MetaData> metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i);
|
||||
if (!metaData.get()) {
|
||||
continue;
|
||||
}
|
||||
int32_t value;
|
||||
if (metaData->findInt32(kKeyTrackID, &value) && value == aTrackID) {
|
||||
return i;
|
||||
|
@ -248,7 +248,7 @@ private:
|
||||
return mSize <= sizeof(u.reservoir);
|
||||
}
|
||||
|
||||
void allocateStorage(size_t size);
|
||||
bool allocateStorage(size_t size);
|
||||
void freeStorage();
|
||||
|
||||
void *storage() {
|
||||
|
@ -420,7 +420,7 @@ uint32_t MPEG4Extractor::flags() const {
|
||||
sp<MetaData> MPEG4Extractor::getMetaData() {
|
||||
status_t err;
|
||||
if ((err = readMetaData()) != OK) {
|
||||
return new MetaData;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mFileMetaData;
|
||||
@ -514,14 +514,15 @@ status_t MPEG4Extractor::readMetaData() {
|
||||
uint64_t psshsize = 0;
|
||||
for (size_t i = 0; i < mPssh.Length(); i++) {
|
||||
psshsize += 20 + mPssh[i].datalen;
|
||||
}
|
||||
if (psshsize > kMAX_ALLOCATION) {
|
||||
return ERROR_MALFORMED;
|
||||
if (mPssh[i].datalen > kMAX_ALLOCATION - 20 ||
|
||||
psshsize > kMAX_ALLOCATION) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
}
|
||||
if (psshsize) {
|
||||
char *buf = (char*)malloc(psshsize);
|
||||
if (!buf) {
|
||||
return ERROR_MALFORMED;
|
||||
return -ENOMEM;
|
||||
}
|
||||
char *ptr = buf;
|
||||
for (size_t i = 0; i < mPssh.Length(); i++) {
|
||||
@ -685,7 +686,10 @@ status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
sinf->len = dataLen - 3;
|
||||
sinf->IPMPData = new char[sinf->len];
|
||||
sinf->IPMPData = new (fallible) char[sinf->len];
|
||||
if (!sinf->IPMPData) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
|
||||
return ERROR_IO;
|
||||
@ -1146,7 +1150,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
|
||||
|
||||
// Copy the contents of the box (including header) verbatim.
|
||||
pssh.datalen = chunk_data_size + 8;
|
||||
pssh.data = new uint8_t[pssh.datalen];
|
||||
pssh.data = new (fallible) uint8_t[pssh.datalen];
|
||||
if (!pssh.data) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (mDataSource->readAt(data_offset - 8, pssh.data, pssh.datalen) < pssh.datalen) {
|
||||
return ERROR_IO;
|
||||
}
|
||||
@ -1762,7 +1769,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
|
||||
sp<ABuffer> buffer = new ABuffer(chunk_data_size);
|
||||
sp<ABuffer> buffer = new (fallible) ABuffer(chunk_data_size);
|
||||
if (!buffer.get()) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (mDataSource->readAt(
|
||||
data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
|
||||
@ -1996,7 +2006,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
|
||||
if (size >= kMAX_ALLOCATION - chunk_size) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
uint8_t *buffer = new uint8_t[size + chunk_size];
|
||||
uint8_t *buffer = new (fallible) uint8_t[size + chunk_size];
|
||||
if (!buffer) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
memcpy(buffer, data, size);
|
||||
@ -2024,12 +2037,18 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
|
||||
if (mFileMetaData != NULL) {
|
||||
ALOGV("chunk_data_size = %lld and data_offset = %lld",
|
||||
chunk_data_size, data_offset);
|
||||
sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
|
||||
const int kSkipBytesOfDataBox = 16;
|
||||
if (chunk_data_size <= kSkipBytesOfDataBox) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
sp<ABuffer> buffer = new (fallible) ABuffer(chunk_data_size + 1);
|
||||
if (!buffer.get()) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (mDataSource->readAt(
|
||||
data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
|
||||
return ERROR_IO;
|
||||
}
|
||||
const int kSkipBytesOfDataBox = 16;
|
||||
mFileMetaData->setData(
|
||||
kKeyAlbumArt, MetaData::TYPE_NONE,
|
||||
buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
|
||||
|
@ -220,7 +220,7 @@ bool MetaData::findData(uint32_t key, uint32_t *type,
|
||||
}
|
||||
|
||||
MetaData::typed_data::typed_data()
|
||||
: mType(0),
|
||||
: mType(TYPE_NONE),
|
||||
mSize(0) {
|
||||
}
|
||||
|
||||
@ -231,17 +231,19 @@ MetaData::typed_data::~typed_data() {
|
||||
MetaData::typed_data::typed_data(const typed_data &from)
|
||||
: mType(from.mType),
|
||||
mSize(0) {
|
||||
allocateStorage(from.mSize);
|
||||
memcpy(storage(), from.storage(), mSize);
|
||||
if (allocateStorage(from.mSize)) {
|
||||
memcpy(storage(), from.storage(), mSize);
|
||||
}
|
||||
}
|
||||
|
||||
MetaData::typed_data &MetaData::typed_data::operator=(
|
||||
const MetaData::typed_data &from) {
|
||||
if (this != &from) {
|
||||
clear();
|
||||
mType = from.mType;
|
||||
allocateStorage(from.mSize);
|
||||
memcpy(storage(), from.storage(), mSize);
|
||||
if (allocateStorage(from.mSize)) {
|
||||
mType = from.mType;
|
||||
memcpy(storage(), from.storage(), mSize);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
@ -250,16 +252,17 @@ MetaData::typed_data &MetaData::typed_data::operator=(
|
||||
void MetaData::typed_data::clear() {
|
||||
freeStorage();
|
||||
|
||||
mType = 0;
|
||||
mType = TYPE_NONE;
|
||||
}
|
||||
|
||||
void MetaData::typed_data::setData(
|
||||
uint32_t type, const void *data, size_t size) {
|
||||
clear();
|
||||
|
||||
mType = type;
|
||||
allocateStorage(size);
|
||||
memcpy(storage(), data, size);
|
||||
if (allocateStorage(size)) {
|
||||
mType = type;
|
||||
memcpy(storage(), data, size);
|
||||
}
|
||||
}
|
||||
|
||||
void MetaData::typed_data::getData(
|
||||
@ -269,14 +272,22 @@ void MetaData::typed_data::getData(
|
||||
*data = storage();
|
||||
}
|
||||
|
||||
void MetaData::typed_data::allocateStorage(size_t size) {
|
||||
bool MetaData::typed_data::allocateStorage(size_t size) {
|
||||
// Update mSize now, as it is needed by usesReservoir() below.
|
||||
// (mSize will be reset if the allocation fails further below.)
|
||||
mSize = size;
|
||||
|
||||
if (usesReservoir()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
u.ext_data = malloc(mSize);
|
||||
if (!u.ext_data) {
|
||||
mType = TYPE_NONE;
|
||||
mSize = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MetaData::typed_data::freeStorage() {
|
||||
|
@ -174,7 +174,8 @@ static const TestFileData testFiles[] = {
|
||||
{ "test_case_1185230.mp4", 1, 320, 240, 1 },
|
||||
{ "test_case_1187067.mp4", 1, 160, 90, 0 },
|
||||
{ "test_case_1200326.mp4", 0, 0, 0, 0 },
|
||||
{ "test_case_1204580.mp4", 1, 320, 180, 0 }
|
||||
{ "test_case_1204580.mp4", 1, 320, 180, 0 },
|
||||
{ "test_case_1216748.mp4", 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
TEST(stagefright_MPEG4Metadata, test_case_mp4)
|
||||
|
@ -22,6 +22,7 @@ TEST_HARNESS_FILES.gtest += [
|
||||
'test_case_1187067.mp4',
|
||||
'test_case_1200326.mp4',
|
||||
'test_case_1204580.mp4',
|
||||
'test_case_1216748.mp4',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_RUST']:
|
||||
|
BIN
media/libstagefright/gtest/test_case_1216748.mp4
Executable file
BIN
media/libstagefright/gtest/test_case_1216748.mp4
Executable file
Binary file not shown.
@ -73,33 +73,34 @@ int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *p
|
||||
nr_socket_getaddr(sock,&ctx->my_addr);
|
||||
nr_transport_addr_copy(&ctx->peer_addr,peer);
|
||||
|
||||
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
|
||||
if (RTO != 0)
|
||||
ctx->rto_ms = RTO;
|
||||
else
|
||||
ctx->rto_ms = 100;
|
||||
if (RTO != 0) {
|
||||
ctx->rto_ms = RTO;
|
||||
} else if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
|
||||
ctx->rto_ms = 100;
|
||||
}
|
||||
|
||||
if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor))
|
||||
ctx->retransmission_backoff_factor = 2.0;
|
||||
ctx->retransmission_backoff_factor = 2.0;
|
||||
|
||||
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits))
|
||||
ctx->maximum_transmits = 7;
|
||||
ctx->maximum_transmits = 7;
|
||||
|
||||
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->final_retransmit_backoff_ms))
|
||||
ctx->final_retransmit_backoff_ms = 16 * ctx->rto_ms;
|
||||
if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->maximum_transmits_timeout_ms))
|
||||
ctx->maximum_transmits_timeout_ms = 16 * ctx->rto_ms;
|
||||
|
||||
ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD;
|
||||
if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) ||
|
||||
!allow_loopback) {
|
||||
ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK;
|
||||
}
|
||||
ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD;
|
||||
if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) ||
|
||||
!allow_loopback) {
|
||||
ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK;
|
||||
}
|
||||
|
||||
/* If we are doing TCP, compute the maximum timeout as if
|
||||
we retransmitted and then set the maximum number of
|
||||
transmits to 1 and the timeout to maximum timeout*/
|
||||
if (ctx->my_addr.protocol == IPPROTO_TCP) {
|
||||
ctx->timeout_ms = ctx->final_retransmit_backoff_ms;
|
||||
/* Because TCP is reliable there is only one final timeout value.
|
||||
* We store the timeout value for TCP in here, because timeout_ms gets
|
||||
* reset to 0 in client_reset() which gets called from client_start() */
|
||||
ctx->maximum_transmits_timeout_ms = ctx->rto_ms *
|
||||
pow(ctx->retransmission_backoff_factor,
|
||||
ctx->maximum_transmits);
|
||||
ctx->maximum_transmits = 1;
|
||||
}
|
||||
|
||||
@ -393,18 +394,25 @@ static int nr_stun_client_send_request(nr_stun_client_ctx *ctx)
|
||||
* response */
|
||||
}
|
||||
else {
|
||||
if (ctx->request_ct < ctx->maximum_transmits) {
|
||||
ctx->timeout_ms *= ctx->retransmission_backoff_factor;
|
||||
ctx->timeout_ms += ctx->rto_ms;
|
||||
if (ctx->request_ct >= ctx->maximum_transmits) {
|
||||
/* Reliable transport only get here once. Unreliable get here for
|
||||
* their final timeout. */
|
||||
ctx->timeout_ms += ctx->maximum_transmits_timeout_ms;
|
||||
}
|
||||
else if (ctx->timeout_ms) {
|
||||
/* exponential backoff */
|
||||
ctx->timeout_ms *= ctx->retransmission_backoff_factor;
|
||||
}
|
||||
else {
|
||||
ctx->timeout_ms += ctx->final_retransmit_backoff_ms;
|
||||
/* initial timeout unreliable transports */
|
||||
ctx->timeout_ms = ctx->rto_ms;
|
||||
}
|
||||
|
||||
r_log(NR_LOG_STUN,LOG_DEBUG,"STUN-CLIENT(%s): Next timer will fire in %u ms",ctx->label, ctx->timeout_ms);
|
||||
|
||||
gettimeofday(&ctx->timer_set, 0);
|
||||
|
||||
assert(ctx->timeout_ms);
|
||||
NR_ASYNC_TIMER_SET(ctx->timeout_ms, nr_stun_client_timer_expired_cb, ctx, &ctx->timer_handle);
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ struct nr_stun_client_ctx_ {
|
||||
UINT4 rto_ms; /* retransmission time out */
|
||||
double retransmission_backoff_factor;
|
||||
UINT4 maximum_transmits;
|
||||
UINT4 final_retransmit_backoff_ms;
|
||||
UINT4 maximum_transmits_timeout_ms;
|
||||
UINT4 mapped_addr_check_mask; /* What checks to run on mapped addresses */
|
||||
int timeout_ms;
|
||||
struct timeval timer_set;
|
||||
|
@ -22,9 +22,6 @@ final class DisplayPortCalculator {
|
||||
private static final String LOGTAG = "GeckoDisplayPort";
|
||||
private static final PointF ZERO_VELOCITY = new PointF(0, 0);
|
||||
|
||||
// Keep this in sync with the TILEDLAYERBUFFER_TILE_SIZE defined in gfx/layers/TiledLayerBuffer.h
|
||||
private static final int TILE_SIZE = 256;
|
||||
|
||||
private static final String PREF_DISPLAYPORT_STRATEGY = "gfx.displayport.strategy";
|
||||
private static final String PREF_DISPLAYPORT_FM_MULTIPLIER = "gfx.displayport.strategy_fm.multiplier";
|
||||
private static final String PREF_DISPLAYPORT_FM_DANGER_X = "gfx.displayport.strategy_fm.danger_x";
|
||||
@ -173,20 +170,19 @@ final class DisplayPortCalculator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the given margins such that when they are applied on the viewport, the resulting rect
|
||||
* does not have any partial tiles, except when it is clipped by the page bounds. This assumes
|
||||
* the tiles are TILE_SIZE by TILE_SIZE and start at the origin, such that there will always be
|
||||
* a tile at (0,0)-(TILE_SIZE,TILE_SIZE)).
|
||||
* Calculate the display port by expanding the viewport by the specified
|
||||
* margins, then clamping to the page size.
|
||||
*/
|
||||
private static DisplayPortMetrics getTileAlignedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) {
|
||||
private static DisplayPortMetrics getPageClampedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) {
|
||||
float left = metrics.viewportRectLeft - margins.left;
|
||||
float top = metrics.viewportRectTop - margins.top;
|
||||
float right = metrics.viewportRectRight() + margins.right;
|
||||
float bottom = metrics.viewportRectBottom() + margins.bottom;
|
||||
left = (float) Math.max(metrics.pageRectLeft, TILE_SIZE * Math.floor(left / TILE_SIZE));
|
||||
top = (float) Math.max(metrics.pageRectTop, TILE_SIZE * Math.floor(top / TILE_SIZE));
|
||||
right = (float) Math.min(metrics.pageRectRight, TILE_SIZE * Math.ceil(right / TILE_SIZE));
|
||||
bottom = (float) Math.min(metrics.pageRectBottom, TILE_SIZE * Math.ceil(bottom / TILE_SIZE));
|
||||
left = Math.max(metrics.pageRectLeft, left);
|
||||
top = Math.max(metrics.pageRectTop, top);
|
||||
right = Math.min(metrics.pageRectRight, right);
|
||||
bottom = Math.min(metrics.pageRectBottom, bottom);
|
||||
|
||||
return new DisplayPortMetrics(left, top, right, bottom, zoom);
|
||||
}
|
||||
|
||||
@ -311,7 +307,7 @@ final class DisplayPortCalculator {
|
||||
margins.bottom = verticalBuffer - margins.top;
|
||||
margins = shiftMarginsForPageBounds(margins, metrics);
|
||||
|
||||
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -422,7 +418,7 @@ final class DisplayPortCalculator {
|
||||
RectF margins = velocityBiasedMargins(horizontalBuffer, verticalBuffer, velocity);
|
||||
margins = shiftMarginsForPageBounds(margins, metrics);
|
||||
|
||||
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -689,7 +685,7 @@ final class DisplayPortCalculator {
|
||||
if (velocity.length() < VELOCITY_THRESHOLD) {
|
||||
// if we're going slow, expand the displayport to 9x viewport size
|
||||
RectF margins = new RectF(width, height, width, height);
|
||||
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
}
|
||||
|
||||
// figure out how far we expect to be
|
||||
@ -714,7 +710,7 @@ final class DisplayPortCalculator {
|
||||
-Math.min(minDy, maxDy),
|
||||
Math.max(minDx, maxDx),
|
||||
Math.max(minDy, maxDy));
|
||||
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -12,30 +12,27 @@ class TestEmulatorContent(MarionetteTestCase):
|
||||
@skip_if_desktop
|
||||
def test_emulator_cmd(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
expected = ["<build>",
|
||||
"OK"]
|
||||
result = self.marionette.execute_async_script("""
|
||||
runEmulatorCmd("avd name", marionetteScriptFinished)
|
||||
""");
|
||||
self.assertEqual(result, expected)
|
||||
expected = ["<build>", "OK"]
|
||||
res = self.marionette.execute_async_script(
|
||||
"runEmulatorCmd('avd name', marionetteScriptFinished)");
|
||||
self.assertEqual(res, expected)
|
||||
|
||||
@skip_if_desktop
|
||||
def test_emulator_shell(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
expected = ["Hello World!"]
|
||||
result = self.marionette.execute_async_script("""
|
||||
runEmulatorShell(["echo", "Hello World!"], marionetteScriptFinished)
|
||||
""");
|
||||
self.assertEqual(result, expected)
|
||||
res = self.marionette.execute_async_script(
|
||||
"runEmulatorShell(['echo', 'Hello World!'], marionetteScriptFinished)")
|
||||
self.assertEqual(res, expected)
|
||||
|
||||
@skip_if_desktop
|
||||
def test_emulator_order(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
self.assertRaises(MarionetteException,
|
||||
self.marionette.execute_async_script,
|
||||
"""runEmulatorCmd("gsm status", function(result) {});
|
||||
marionetteScriptFinished(true);
|
||||
""");
|
||||
with self.assertRaises(MarionetteException):
|
||||
self.marionette.execute_async_script("""
|
||||
runEmulatorCmd("gsm status", function(res) {});
|
||||
marionetteScriptFinished(true);
|
||||
""")
|
||||
|
||||
|
||||
class TestEmulatorChrome(TestEmulatorContent):
|
||||
@ -132,6 +129,24 @@ class TestEmulatorCallbacks(MarionetteTestCase):
|
||||
with self.assertRaisesRegexp(JavascriptException, "TypeError"):
|
||||
self.marionette.execute_async_script("runEmulatorCmd()")
|
||||
|
||||
def test_multiple_callbacks(self):
|
||||
res = self.marionette.execute_async_script("""
|
||||
runEmulatorCmd("what");
|
||||
runEmulatorCmd("ho");
|
||||
marionetteScriptFinished("Frobisher");
|
||||
""")
|
||||
self.assertEqual("Frobisher", res)
|
||||
|
||||
# This should work, but requires work on emulator callbacks:
|
||||
"""
|
||||
def test_multiple_nested_callbacks(self):
|
||||
res = self.marionette.execute_async_script('''
|
||||
runEmulatorCmd("what", function(res) {
|
||||
runEmulatorCmd("ho", marionetteScriptFinished);
|
||||
});''')
|
||||
self.assertEqual("cmd response", res)
|
||||
"""
|
||||
|
||||
|
||||
def escape(word):
|
||||
return "'%s'" % word
|
||||
|
@ -671,6 +671,27 @@ class Marionette(object):
|
||||
|
||||
@do_crash_check
|
||||
def _send_message(self, name, params=None, key=None):
|
||||
"""Send a blocking message to the server.
|
||||
|
||||
Marionette provides an asynchronous, non-blocking interface and
|
||||
this attempts to paper over this by providing a synchronous API
|
||||
to the user.
|
||||
|
||||
In particular, the Python client can be instructed to carry out
|
||||
a sequence of instructions on the connected emulator. For this
|
||||
reason, if ``execute_script``, ``execute_js_script``, or
|
||||
``execute_async_script`` is called, it will loop until all
|
||||
commands requested from the server have been exhausted, and we
|
||||
receive our expected response.
|
||||
|
||||
:param name: Requested command key.
|
||||
:param params: Optional dictionary of key/value arguments.
|
||||
:param key: Optional key to extract from response.
|
||||
|
||||
:returns: Full response from the server, or if `key` is given,
|
||||
the value of said key in the response.
|
||||
"""
|
||||
|
||||
if not self.session_id and name != "newSession":
|
||||
raise errors.MarionetteException("Please start a session")
|
||||
|
||||
@ -692,13 +713,16 @@ class Marionette(object):
|
||||
returncode = self.instance.runner.wait(timeout=self.DEFAULT_STARTUP_TIMEOUT)
|
||||
raise IOError("process died with returncode %s" % returncode)
|
||||
raise
|
||||
|
||||
except socket.timeout:
|
||||
self.session = None
|
||||
self.window = None
|
||||
self.client.close()
|
||||
raise errors.TimeoutException("Connection timed out")
|
||||
|
||||
if isinstance(msg, transport.Command):
|
||||
# support execution of commands on the client,
|
||||
# loop until we receive our expected response
|
||||
while isinstance(msg, transport.Command):
|
||||
if msg.name == "runEmulatorCmd":
|
||||
self.emulator_callback_id = msg.params.get("id")
|
||||
msg = self._emulator_cmd(msg.params["emulator_cmd"])
|
||||
|
@ -114,7 +114,7 @@ ContentSender.prototype.send = function(name, args) {
|
||||
let rmFn = msg => {
|
||||
if (this.curId !== msg.json.command_id) {
|
||||
logger.warn("Skipping out-of-sync response from listener: " +
|
||||
`Expected response to \`${name}' with ID ${this.curId}, ` +
|
||||
`Expected response to ${name} with ID ${this.curId}, ` +
|
||||
"but got: " + msg.name + msg.json.toSource());
|
||||
return;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ function url_test(name, url) {
|
||||
}
|
||||
|
||||
url_test('relative', 'resources/empty-worker.js');
|
||||
url_test('with-fragment', 'resources/empty-worker.js#ref');
|
||||
url_test('absolute', (new URL('./resources/empty-worker.js', window.location)).href);
|
||||
|
||||
</script>
|
||||
|
@ -1 +0,0 @@
|
||||
%/dump_syms.mm: ;
|
@ -1 +0,0 @@
|
||||
%/dump_syms_tool.mm: ;
|
@ -111,6 +111,19 @@ def paramlistAsNative(m, empty='void'):
|
||||
location=None,
|
||||
realtype=m.realtype)))
|
||||
|
||||
# Set any optional out params to default to nullptr. Skip if we just added
|
||||
# extra non-optional args to l.
|
||||
if len(l) == len(m.params):
|
||||
paramIter = len(m.params) - 1
|
||||
while (paramIter >= 0 and m.params[paramIter].optional and
|
||||
m.params[paramIter].paramtype == "out"):
|
||||
t = m.params[paramIter].type
|
||||
# Strings can't be optional, so this shouldn't happen, but let's make sure:
|
||||
if t == "AString" or t == "ACString" or t == "DOMString" or t == "AUTF8String":
|
||||
break
|
||||
l[paramIter] += " = nullptr"
|
||||
paramIter -= 1
|
||||
|
||||
if len(l) == 0:
|
||||
return empty
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user