merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-09-19 14:11:44 +02:00
commit 751ead3179
52 changed files with 664 additions and 669 deletions

View File

@ -308,4 +308,10 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
return S_OK;
}
void
WMFAudioMFTManager::Shutdown()
{
mDecoder = nullptr;
}
} // namespace mozilla

View File

@ -29,6 +29,9 @@ public:
// a null aOutput in this case.
virtual HRESULT Output(int64_t aStreamOffset,
nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE;
virtual void Shutdown() MOZ_OVERRIDE;
private:
HRESULT UpdateOutputType();

View File

@ -48,10 +48,18 @@ WMFMediaDataDecoder::Init()
nsresult
WMFMediaDataDecoder::Shutdown()
{
mDecoder = nullptr;
mTaskQueue->FlushAndDispatch(NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown));
return NS_OK;
}
void
WMFMediaDataDecoder::ProcessShutdown()
{
mMFTManager->Shutdown();
mMFTManager = nullptr;
mDecoder = nullptr;
}
// Inserts data into the decoder's pipeline.
nsresult
WMFMediaDataDecoder::Input(mp4_demuxer::MP4Sample* aSample)

View File

@ -43,6 +43,9 @@ public:
// MP4Reader.
virtual HRESULT Output(int64_t aStreamOffset,
nsAutoPtr<MediaData>& aOutput) = 0;
// Destroys all resources.
virtual void Shutdown() = 0;
};
// Decodes audio and video using Windows Media Foundation. Samples are decoded
@ -81,6 +84,8 @@ private:
// all available output.
void ProcessDrain();
void ProcessShutdown();
RefPtr<MediaTaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;

View File

@ -399,4 +399,10 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
return S_OK;
}
void
WMFVideoMFTManager::Shutdown()
{
mDecoder = nullptr;
}
} // namespace mozilla

View File

@ -33,6 +33,8 @@ public:
virtual HRESULT Output(int64_t aStreamOffset,
nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE;
virtual void Shutdown() MOZ_OVERRIDE;
private:
bool InitializeDXVA();

View File

@ -338,7 +338,7 @@ MediaSource::Detach()
}
mDecoder->DetachMediaSource();
mDecoder = nullptr;
mFirstSourceBufferInitialization = false;
mFirstSourceBufferInitialized = false;
SetReadyState(MediaSourceReadyState::Closed);
mDuration = UnspecifiedNaN<double>();
if (mActiveSourceBuffers) {
@ -395,7 +395,7 @@ MediaSource::MediaSource(nsPIDOMWindow* aWindow)
, mDuration(UnspecifiedNaN<double>())
, mDecoder(nullptr)
, mReadyState(MediaSourceReadyState::Closed)
, mFirstSourceBufferInitialization(false)
, mFirstSourceBufferInitialized(false)
{
MOZ_ASSERT(NS_IsMainThread());
mSourceBuffers = new SourceBufferList(this);
@ -487,9 +487,10 @@ void
MediaSource::QueueInitializationEvent()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mFirstSourceBufferInitialization) {
mFirstSourceBufferInitialization = true;
if (mFirstSourceBufferInitialized) {
return;
}
mFirstSourceBufferInitialized = true;
MSE_DEBUG("MediaSource(%p)::QueueInitializationEvent()", this);
nsRefPtr<nsIRunnable> task =
NS_NewRunnableMethod(this, &MediaSource::InitializationEvent);

View File

@ -92,7 +92,7 @@ public:
// Queue InitializationEvent to run on the main thread. Called when a
// SourceBuffer has an initialization segment appended, but only
// dispatched the first time (using mFirstSourceBufferInitialization).
// dispatched the first time (using mFirstSourceBufferInitialized).
// Demarcates the point in time at which only currently registered
// TrackBuffers are treated as essential by the MediaSourceReader for
// initialization.
@ -130,7 +130,7 @@ private:
MediaSourceReadyState mReadyState;
bool mFirstSourceBufferInitialization;
bool mFirstSourceBufferInitialized;
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)

View File

@ -473,7 +473,10 @@ MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
this, mEssentialTrackBuffers.Length(), mTrackBuffers.Length(),
mAudioTrack.get(), mVideoTrack.get());
mEssentialTrackBuffers.Clear();
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mEssentialTrackBuffers.Clear();
}
if (!mAudioTrack && !mVideoTrack) {
MSE_DEBUG("MediaSourceReader(%p)::ReadMetadata missing track: mAudioTrack=%p mVideoTrack=%p",
this, mAudioTrack.get(), mVideoTrack.get());

Binary file not shown.

View File

@ -0,0 +1 @@
Cache-Control: no-store

View File

@ -187,6 +187,7 @@ var gPlayTests = [
{ name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
// Opus data in a webm container
{ name:"detodos.webm", type:"audio/webm; codecs=opus", duration:2.9135 },
{ name:"bug1066943.webm", type:"audio/webm; codecs=opus", duration:1.383 },
// Multichannel Opus in an ogg container
{ name:"test-1-mono.opus", type:"audio/ogg; codecs=opus", duration:1.044 },

View File

@ -107,6 +107,8 @@ support-files =
bug604067.webm
bug604067.webm^headers^
bug883173.vtt
bug1066943.webm
bug1066943.webm^headers^
can_play_type_dash.js
can_play_type_ogg.js
can_play_type_wave.js

View File

@ -556,8 +556,8 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
#ifdef DEBUG
CheckedInt64 usecs = FramesToUsecs(tstamp_frames.value() - decoded_frames.value(), rate);
LOG(PR_LOG_DEBUG, ("WebMReader detected gap of %lld, %lld frames, in audio stream\n",
usecs.isValid() ? usecs.value() : -1,
tstamp_frames.value() - decoded_frames.value()));
usecs.isValid() ? usecs.value() : -1,
tstamp_frames.value() - decoded_frames.value()));
#endif
mPacketCount++;
mAudioStartUsec = tstamp_usecs;
@ -671,8 +671,7 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
int32_t keepFrames = frames - skipFrames;
int samples = keepFrames * channels;
nsAutoArrayPtr<AudioDataValue> trimBuffer(new AudioDataValue[samples]);
for (int i = 0; i < samples; i++)
trimBuffer[i] = buffer[skipFrames*channels + i];
PodCopy(trimBuffer.get(), buffer.get() + skipFrames*channels, samples);
startTime = startTime + FramesToUsecs(skipFrames, rate);
frames = keepFrames;
buffer = trimBuffer;
@ -684,24 +683,23 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
int64_t discardPadding = 0;
r = nestegg_packet_discard_padding(aPacket, &discardPadding);
if (discardPadding > 0) {
CheckedInt64 discardFrames = UsecsToFrames(discardPadding * NS_PER_USEC, rate);
CheckedInt64 discardFrames = UsecsToFrames(discardPadding / NS_PER_USEC, rate);
if (!discardFrames.isValid()) {
NS_WARNING("Int overflow in DiscardPadding");
return false;
}
int32_t keepFrames = frames - discardFrames.value();
if (keepFrames > 0) {
int samples = keepFrames * channels;
nsAutoArrayPtr<AudioDataValue> trimBuffer(new AudioDataValue[samples]);
for (int i = 0; i < samples; i++)
trimBuffer[i] = buffer[i];
frames = keepFrames;
buffer = trimBuffer;
} else {
if (discardFrames.value() >= frames) {
LOG(PR_LOG_DEBUG, ("Opus decoder discarding whole packet"
" ( %d frames) as padding", frames));
" (%d frames) as padding (%lld discarded)",
frames, discardFrames.value()));
return true;
}
int32_t keepFrames = frames - discardFrames.value();
int32_t samples = keepFrames * channels;
nsAutoArrayPtr<AudioDataValue> trimBuffer(new AudioDataValue[samples]);
PodCopy(trimBuffer.get(), buffer.get(), samples);
frames = keepFrames;
buffer = trimBuffer;
}
// Apply the header gain if one was specified.

View File

@ -3405,6 +3405,7 @@ class IDLArgument(IDLObjectWithIdentifier):
self._allowTreatNonCallableAsNull = False
assert not variadic or optional
assert not variadic or not defaultValue
def addExtendedAttributes(self, attrs):
attrs = self.checkForStringHandlingExtendedAttributes(
@ -3453,9 +3454,9 @@ class IDLArgument(IDLObjectWithIdentifier):
if ((self.type.isDictionary() or
self.type.isUnion() and self.type.unroll().hasDictionaryType) and
self.optional and not self.defaultValue):
# Default optional dictionaries to null, for simplicity,
# so the codegen doesn't have to special-case this.
self.optional and not self.defaultValue and not self.variadic):
# Default optional non-variadic dictionaries to null,
# for simplicity, so the codegen doesn't have to special-case this.
self.defaultValue = IDLNullValue(self.location)
elif self.type.isAny():
assert (self.defaultValue is None or

View File

@ -714,6 +714,7 @@ public:
void PassDictContainingDict(JSContext*, const DictContainingDict&);
void PassDictContainingSequence(JSContext*, const DictContainingSequence&);
void ReceiveDictContainingSequence(JSContext*, DictContainingSequence&);
void PassVariadicDictionary(JSContext*, const Sequence<Dict>&);
// Typedefs
void ExerciseTypedefInterfaces1(TestInterface&);

View File

@ -686,6 +686,7 @@ interface TestInterface {
void passDictContainingDict(optional DictContainingDict arg);
void passDictContainingSequence(optional DictContainingSequence arg);
DictContainingSequence receiveDictContainingSequence();
void passVariadicDictionary(Dict... arg);
// EnforceRange/Clamp tests
void dontEnforceRangeOrClamp(byte arg);

View File

@ -550,6 +550,7 @@ interface TestExampleInterface {
void passDictContainingDict(optional DictContainingDict arg);
void passDictContainingSequence(optional DictContainingSequence arg);
DictContainingSequence receiveDictContainingSequence();
void passVariadicDictionary(Dict... arg);
// EnforceRange/Clamp tests
void dontEnforceRangeOrClamp(byte arg);

View File

@ -136,9 +136,8 @@ interface TestJSImplInterface {
TestJSImplInterface receiveSelf();
TestJSImplInterface? receiveNullableSelf();
// Callback interface ignores 'resultNotAddRefed'. See bug 843272.
//TestJSImplInterface receiveWeakSelf();
//TestJSImplInterface? receiveWeakNullableSelf();
TestJSImplInterface receiveWeakSelf();
TestJSImplInterface? receiveWeakNullableSelf();
// A version to test for casting to TestJSImplInterface&
void passSelf(TestJSImplInterface arg);
@ -170,9 +169,8 @@ interface TestJSImplInterface {
// Non-castable interface types
IndirectlyImplementedInterface receiveOther();
IndirectlyImplementedInterface? receiveNullableOther();
// Callback interface ignores 'resultNotAddRefed'. See bug 843272.
//IndirectlyImplementedInterface receiveWeakOther();
//IndirectlyImplementedInterface? receiveWeakNullableOther();
IndirectlyImplementedInterface receiveWeakOther();
IndirectlyImplementedInterface? receiveWeakNullableOther();
void passOther(IndirectlyImplementedInterface arg);
void passNullableOther(IndirectlyImplementedInterface? arg);
@ -186,9 +184,8 @@ interface TestJSImplInterface {
// External interface types
TestExternalInterface receiveExternal();
TestExternalInterface? receiveNullableExternal();
// Callback interface ignores 'resultNotAddRefed'. See bug 843272.
//TestExternalInterface receiveWeakExternal();
//TestExternalInterface? receiveWeakNullableExternal();
TestExternalInterface receiveWeakExternal();
TestExternalInterface? receiveWeakNullableExternal();
void passExternal(TestExternalInterface arg);
void passNullableExternal(TestExternalInterface? arg);
attribute TestExternalInterface nonNullExternal;
@ -201,9 +198,8 @@ interface TestJSImplInterface {
// Callback interface types
TestCallbackInterface receiveCallbackInterface();
TestCallbackInterface? receiveNullableCallbackInterface();
// Callback interface ignores 'resultNotAddRefed'. See bug 843272.
//TestCallbackInterface receiveWeakCallbackInterface();
//TestCallbackInterface? receiveWeakNullableCallbackInterface();
TestCallbackInterface receiveWeakCallbackInterface();
TestCallbackInterface? receiveWeakNullableCallbackInterface();
void passCallbackInterface(TestCallbackInterface arg);
void passNullableCallbackInterface(TestCallbackInterface? arg);
attribute TestCallbackInterface nonNullCallbackInterface;
@ -570,6 +566,7 @@ interface TestJSImplInterface {
void passDictContainingDict(optional DictContainingDict arg);
void passDictContainingSequence(optional DictContainingSequence arg);
DictContainingSequence receiveDictContainingSequence();
void passVariadicDictionary(Dict... arg);
// EnforceRange/Clamp tests
void dontEnforceRangeOrClamp(byte arg);

View File

@ -145,6 +145,11 @@ public:
/*
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
*/
void ClearBufferiv_base(GLenum buffer, GLint drawbuffer, const GLint* value);
void ClearBufferuiv_base(GLenum buffer, GLint drawbuffer, const GLuint* value);
void ClearBufferfv_base(GLenum buffer, GLint drawbuffer, const GLfloat* value);
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value);
void ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLint>& value);
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value);
@ -153,6 +158,7 @@ public:
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLfloat>& value);
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
bool ValidateClearBuffer(const char* info, GLenum buffer, GLint drawbuffer, size_t elemCount);
// -------------------------------------------------------------------------
// Query Objects - WebGL2ContextQueries.cpp

View File

@ -9,44 +9,134 @@
using namespace mozilla;
using namespace mozilla::dom;
bool WebGL2Context::ValidateClearBuffer(const char* info, GLenum buffer, GLint drawbuffer, size_t elemCount)
{
size_t requiredElements = -1;
GLint maxDrawbuffer = -1;
switch (buffer) {
case LOCAL_GL_COLOR:
case LOCAL_GL_FRONT:
case LOCAL_GL_BACK:
case LOCAL_GL_LEFT:
case LOCAL_GL_RIGHT:
case LOCAL_GL_FRONT_AND_BACK:
requiredElements = 4;
maxDrawbuffer = mGLMaxDrawBuffers - 1;
break;
case LOCAL_GL_DEPTH:
case LOCAL_GL_STENCIL:
requiredElements = 1;
maxDrawbuffer = 0;
break;
default:
ErrorInvalidEnumInfo(info, buffer);
return false;
}
if (drawbuffer < 0 || drawbuffer > maxDrawbuffer) {
ErrorInvalidValue("%s: invalid drawbuffer %d. This buffer only supports drawbuffer values between 0 and %d",
info, drawbuffer, maxDrawbuffer);
return false;
}
if (elemCount < requiredElements) {
ErrorInvalidValue("%s: Not enough elements. Require %u. Given %u.",
info, requiredElements, elemCount);
return false;
}
return true;
}
// Common base functionality. These a good candidates to be moved into WebGLContextUnchecked.cpp
void
WebGL2Context::ClearBufferiv_base(GLenum buffer, GLint drawbuffer, const GLint* value)
{
MakeContextCurrent();
gl->fClearBufferiv(buffer, drawbuffer, value);
}
void
WebGL2Context::ClearBufferuiv_base(GLenum buffer, GLint drawbuffer, const GLuint* value)
{
MakeContextCurrent();
gl->fClearBufferuiv(buffer, drawbuffer, value);
}
void
WebGL2Context::ClearBufferfv_base(GLenum buffer, GLint drawbuffer, const GLfloat* value)
{
MakeContextCurrent();
gl->fClearBufferfv(buffer, drawbuffer, value);
}
void
WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferiv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferiv_base(buffer, drawbuffer, value.Data());
}
void
WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLint>& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferiv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferiv_base(buffer, drawbuffer, value.Elements());
}
void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferuiv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferuiv_base(buffer, drawbuffer, value.Data());
}
void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLuint>& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferuiv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferuiv_base(buffer, drawbuffer, value.Elements());
}
void
WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferfv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferfv_base(buffer, drawbuffer, value.Data());
}
void
WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
if (!ValidateClearBuffer("clearBufferfv", buffer, drawbuffer, value.Length())) {
return;
}
ClearBufferfv_base(buffer, drawbuffer, value.Elements());
}
void
WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
MOZ_CRASH("Not Implemented.");
if (buffer != LOCAL_GL_DEPTH_STENCIL) {
return ErrorInvalidEnumInfo("clearBufferfi: buffer", buffer);
}
MakeContextCurrent();
gl->fClearBufferfi(buffer, drawbuffer, depth, stencil);
}

View File

@ -1388,6 +1388,13 @@ DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFo
bool
DrawTargetCairo::InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
{
if (cairo_surface_status(aSurface)) {
gfxCriticalError() << "Attempt to create DrawTarget for invalid surface. "
<< aSize << " Cairo Status: " << cairo_surface_status(aSurface);
cairo_surface_destroy(aSurface);
return false;
}
mContext = cairo_create(aSurface);
mSurface = aSurface;
mSize = aSize;

View File

@ -1348,7 +1348,7 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
mFormat = aFormat;
if (!Factory::GetDirect3D10Device()) {
gfxDebug() << "Failed to Init Direct2D DrawTarget (No D3D10 Device set.)";
gfxCriticalError() << "Failed to Init Direct2D DrawTarget (No D3D10 Device set.)";
return false;
}
mDevice = Factory::GetDirect3D10Device();
@ -1362,7 +1362,7 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
if (FAILED(hr)) {
gfxDebug() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hr;
gfxCriticalError() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hr;
return false;
}
@ -1393,7 +1393,7 @@ DrawTargetD2D::Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
hr = device->QueryInterface((ID3D10Device1**)byRef(mDevice));
if (FAILED(hr)) {
gfxWarning() << "Failed to get D3D10 device from texture.";
gfxCriticalError() << "Failed to get D3D10 device from texture.";
return false;
}
@ -1512,6 +1512,7 @@ bool
DrawTargetD2D::InitD2DRenderTarget()
{
if (!factory()) {
gfxCriticalError() << "No valid D2D factory available.";
return false;
}
@ -1960,7 +1961,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = aTexture->QueryInterface((IDXGISurface**)byRef(surface));
if (FAILED(hr)) {
gfxWarning() << "Failed to QI texture to surface.";
gfxCriticalError() << "Failed to QI texture to surface.";
return nullptr;
}
@ -1978,7 +1979,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));
if (FAILED(hr)) {
gfxWarning() << "Failed to create D2D render target for texture.";
gfxCriticalError() << "Failed to create D2D render target for texture.";
return nullptr;
}

View File

@ -1012,6 +1012,23 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
if (IsSupported(GLFeature::clear_buffers)) {
SymLoadStruct clearBuffersSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fClearBufferfi, { "ClearBufferfi", nullptr } },
{ (PRFuncPtr*) &mSymbols.fClearBufferfv, { "ClearBufferfv", nullptr } },
{ (PRFuncPtr*) &mSymbols.fClearBufferiv, { "ClearBufferiv", nullptr } },
{ (PRFuncPtr*) &mSymbols.fClearBufferuiv, { "ClearBufferuiv", nullptr } },
END_SYMBOLS
};
if (!LoadSymbols(clearBuffersSymbols, trygl, prefix)) {
NS_ERROR("GL supports clear_buffers without supplying its functions.");
MarkUnsupported(GLFeature::clear_buffers);
ClearSymbols(clearBuffersSymbols);
}
}
if (IsSupported(GLFeature::draw_buffers)) {
SymLoadStruct coreSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } },

View File

@ -80,6 +80,7 @@ namespace gl {
MOZ_BEGIN_ENUM_CLASS(GLFeature)
bind_buffer_offset,
blend_minmax,
clear_buffers,
depth_texture,
draw_buffers,
draw_instanced,
@ -946,6 +947,30 @@ public:
AfterGLDrawCall();
}
void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
BEFORE_GL_CALL;
mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
AFTER_GL_CALL;
}
void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
BEFORE_GL_CALL;
mSymbols.fClearBufferfv(buffer, drawbuffer, value);
AFTER_GL_CALL;
}
void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
BEFORE_GL_CALL;
mSymbols.fClearBufferiv(buffer, drawbuffer, value);
AFTER_GL_CALL;
}
void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
BEFORE_GL_CALL;
mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
AFTER_GL_CALL;
}
void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
BEFORE_GL_CALL;
mSymbols.fClearColor(r, g, b, a);

View File

@ -71,6 +71,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End
}
},
{
"clear_buffers",
300, // OpenGL version
300, // OpenGL ES version
GLContext::Extension_None,
{
GLContext::Extensions_End
}
},
{
"depth_texture",
200, // OpenGL version

View File

@ -65,6 +65,14 @@ struct GLContextSymbols
PFNGLBUFFERSUBDATAPROC fBufferSubData;
typedef void (GLAPIENTRY * PFNGLCLEARPROC) (GLbitfield);
PFNGLCLEARPROC fClear;
typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
PFNGLCLEARBUFFERFIPROC fClearBufferfi;
typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
PFNGLCLEARBUFFERFVPROC fClearBufferfv;
typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint* value);
PFNGLCLEARBUFFERIVPROC fClearBufferiv;
typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint* value);
PFNGLCLEARBUFFERUIVPROC fClearBufferuiv;
typedef void (GLAPIENTRY * PFNGLCLEARCOLORPROC) (GLclampf, GLclampf, GLclampf, GLclampf);
PFNGLCLEARCOLORPROC fClearColor;
typedef void (GLAPIENTRY * PFNGLCLEARSTENCILPROC) (GLint);

View File

@ -252,7 +252,8 @@ public:
image->UnlockImage();
}
if (DiscardingEnabled() && dstFrame) {
if (dstFrame) {
dstFrame->SetOptimizable();
dstFrame->SetDiscardable();
}
@ -1422,21 +1423,17 @@ RasterImage::DecodingComplete()
CONTAINER_ENSURE_SUCCESS(rv);
}
// If there's only 1 frame, optimize it. Optimizing animated images
// If there's only 1 frame, mark it as optimizable. Optimizing animated images
// is not supported.
//
// We don't optimize the frame for multipart images because we reuse
// the frame.
if ((GetNumFrames() == 1) && !mMultipart) {
// CanForciblyDiscard is used instead of CanForciblyDiscardAndRedecode
// because we know decoding is complete at this point and this is not
// an animation
nsRefPtr<imgFrame> firstFrame = mFrameBlender.RawGetFrame(0);
firstFrame->SetOptimizable();
if (DiscardingEnabled() && CanForciblyDiscard()) {
firstFrame->SetDiscardable();
}
rv = firstFrame->Optimize();
NS_ENSURE_SUCCESS(rv, rv);
}
// Double-buffer our frame in the multipart case, since we'll start decoding
@ -2607,6 +2604,11 @@ RasterImage::RequestScale(imgFrame* aFrame, nsIntSize aSize)
return;
}
// We don't scale frames which aren't fully decoded.
if (!aFrame->ImageComplete()) {
return;
}
// We also can't scale if we can't lock the image data for this frame.
RawAccessFrameRef frameRef = aFrame->RawAccessRef();
if (!frameRef) {

View File

@ -122,6 +122,7 @@ imgFrame::imgFrame() :
mCompositingFailed(false),
mNonPremult(false),
mDiscardable(false),
mOptimizable(false),
mInformedDiscardTracker(false)
{
static bool hasCheckedOptimize = false;
@ -298,8 +299,10 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
nsresult imgFrame::Optimize()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mLockCount == 1,
"Should only optimize when holding the lock exclusively");
if (gDisableOptimize)
if (!mOptimizable || gDisableOptimize)
return NS_OK;
if (mPalettedImageData || mOptSurface || mSinglePixel)
@ -401,6 +404,15 @@ nsresult imgFrame::Optimize()
mImageSurface = nullptr;
}
#ifdef MOZ_WIDGET_ANDROID
// On Android, free mImageSurface unconditionally if we're discardable.
// XXX(seth): We'd eventually like to do this on all platforms, but right now
// we'd read back from the GPU too much to make it worthwhile.
if (mDiscardable) {
mImageSurface = nullptr;
}
#endif
return NS_OK;
}
@ -452,7 +464,7 @@ imgFrame::SurfaceForDrawing(bool aDoPadding,
} else {
SurfacePattern pattern(aSurface,
ExtendMode::REPEAT,
ToMatrix(aContext->CurrentMatrix()));
Matrix::Translation(mDecoded.x, mDecoded.y));
target->FillRect(ToRect(aRegion.Intersect(available).Rect()), pattern);
}
@ -719,42 +731,40 @@ nsresult imgFrame::UnlockImageData()
{
MOZ_ASSERT(NS_IsMainThread());
NS_ABORT_IF_FALSE(mLockCount != 0, "Unlocking an unlocked image!");
if (mLockCount == 0) {
MOZ_ASSERT(mLockCount > 0, "Unlocking an unlocked image!");
if (mLockCount <= 0) {
return NS_ERROR_FAILURE;
}
// If we're about to become unlocked, we don't need to hold on to our data
// surface anymore. (But we don't need to do anything for paletted images,
// which don't have surfaces.)
if (mLockCount == 1 && !mPalettedImageData) {
// Convert the data surface to a GPU surface or a single color if possible.
// This will also release mImageSurface if possible.
Optimize();
// Allow the OS to release our data surface.
mVBufPtr = nullptr;
}
mLockCount--;
NS_ABORT_IF_FALSE(mLockCount >= 0, "Unbalanced locks and unlocks");
if (mLockCount < 0) {
return NS_ERROR_FAILURE;
}
// If we are not the last lock, there's nothing to do.
if (mLockCount != 0) {
return NS_OK;
}
// Paletted images don't have surfaces, so there's nothing to do.
if (mPalettedImageData)
return NS_OK;
mVBufPtr = nullptr;
if (mVBuf && mDiscardable) {
mImageSurface = nullptr;
}
return NS_OK;
}
void imgFrame::SetDiscardable()
void
imgFrame::SetDiscardable()
{
MOZ_ASSERT(mLockCount, "Expected to be locked when SetDiscardable is called");
// Disabled elsewhere due to the cost of calling GetSourceSurfaceForSurface.
#ifdef MOZ_WIDGET_ANDROID
mDiscardable = true;
#endif
}
void
imgFrame::SetOptimizable()
{
MOZ_ASSERT(mLockCount, "Expected to be locked when SetOptimizable is called");
mOptimizable = true;
}
TemporaryRef<SourceSurface>

View File

@ -74,8 +74,6 @@ public:
GraphicsFilter aFilter,
uint32_t aImageFlags);
nsresult Optimize();
DrawableFrameRef DrawableRef();
RawAccessFrameRef RawAccessRef();
@ -118,6 +116,7 @@ public:
nsresult UnlockImageData();
void SetDiscardable();
void SetOptimizable();
TemporaryRef<SourceSurface> GetSurface();
TemporaryRef<DrawTarget> GetDrawTarget();
@ -151,6 +150,8 @@ private: // methods
~imgFrame();
nsresult Optimize();
struct SurfaceWithFormat {
nsRefPtr<gfxDrawable> mDrawable;
SurfaceFormat mFormat;
@ -205,6 +206,7 @@ private: // data
bool mCompositingFailed;
bool mNonPremult;
bool mDiscardable;
bool mOptimizable;
/** Have we called DiscardTracker::InformAllocation()? */
bool mInformedDiscardTracker;

View File

@ -22,6 +22,9 @@ skip-if(B2G) random-if(Android) == test_bug641198.html animation2a-finalframe.gi
# Bug 1062886: a gif with a single color and an offset
== one-color-offset.gif one-color-offset-ref.gif
# Bug 1068230
== tile-transform.html tile-transform-ref.html
# webcam-simulacrum.mgif is a hand-edited file containing red.gif and blue.gif,
# concatenated together with the relevant headers for
# multipart/x-mixed-replace. Specifically, with the headers in

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1068230
-->
<html>
<head>
<title>Intermediate surface should be transformed correctly when tiling an image</title>
</head>
<body>
<button style="margin: 10px; padding: 10px; border: none; background: url('tiletest-ref.png');"></button>
</body>
</html>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1068230
-->
<html>
<head>
<title>Intermediate surface should be transformed correctly when tiling an image</title>
</head>
<body>
<button style="margin: 10px; padding: 10px; border: none; background: url('tiletest.gif');"></button>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

View File

@ -49,9 +49,13 @@ CollectLaterSiblings(nsISupports* aElement,
return PL_DHASH_NEXT;
}
struct RestyleEnumerateData : RestyleTracker::Hints {
nsRefPtr<dom::Element> mElement;
};
struct RestyleCollector {
RestyleTracker* tracker;
RestyleTracker::RestyleEnumerateData** restyleArrayPtr;
RestyleEnumerateData** restyleArrayPtr;
};
static PLDHashOperator
@ -91,10 +95,8 @@ CollectRestyles(nsISupports* aElement,
element->UnsetFlags(collector->tracker->RestyleBit() |
collector->tracker->RootBit());
RestyleTracker::RestyleEnumerateData** restyleArrayPtr =
collector->restyleArrayPtr;
RestyleTracker::RestyleEnumerateData* currentRestyle =
*restyleArrayPtr;
RestyleEnumerateData** restyleArrayPtr = collector->restyleArrayPtr;
RestyleEnumerateData* currentRestyle = *restyleArrayPtr;
currentRestyle->mElement = element;
currentRestyle->mRestyleHint = aData->mRestyleHint;
currentRestyle->mChangeHint = aData->mChangeHint;
@ -231,8 +233,6 @@ RestyleTracker::DoProcessRestyles()
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint);
MOZ_ASSERT(currentRestyle->mDescendants.IsEmpty());
}
}
}

View File

@ -287,7 +287,12 @@ public:
return mRestyleBits & ~ELEMENT_PENDING_RESTYLE_FLAGS;
}
struct RestyleData {
struct Hints {
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
};
struct RestyleData : Hints {
RestyleData() {
mRestyleHint = nsRestyleHint(0);
mChangeHint = NS_STYLE_HINT_NONE;
@ -298,9 +303,6 @@ public:
mChangeHint = aChangeHint;
}
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
// Descendant elements we must check that we ended up restyling, ordered
// with the same invariant as mRestyleRoots. The elements here are those
// that we called AddPendingRestyle for and found the element this is
@ -340,10 +342,6 @@ public:
*/
inline nsIDocument* Document() const;
struct RestyleEnumerateData : public RestyleData {
nsRefPtr<Element> mElement;
};
private:
bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
@ -474,7 +472,12 @@ RestyleTracker::AddPendingRestyle(Element* aElement,
RestyleData* curData;
mPendingRestyles.Get(cur, &curData);
NS_ASSERTION(curData, "expected to find a RestyleData for cur");
curData->mDescendants.AppendElement(aElement);
// If cur has an eRestyle_ForceDescendants restyle hint, then we
// know that we will get to all descendants. Don't bother
// recording the descendant to restyle in that case.
if (!(curData->mRestyleHint & eRestyle_ForceDescendants)) {
curData->mDescendants.AppendElement(aElement);
}
}
}

View File

@ -4467,8 +4467,8 @@ nsDocumentViewer::InitializeForPrintPreview()
void
nsDocumentViewer::SetPrintPreviewPresentation(nsViewManager* aViewManager,
nsPresContext* aPresContext,
nsIPresShell* aPresShell)
nsPresContext* aPresContext,
nsIPresShell* aPresShell)
{
if (mPresShell) {
DestroyPresShell();
@ -4478,6 +4478,13 @@ nsDocumentViewer::SetPrintPreviewPresentation(nsViewManager* aViewManager,
mViewManager = aViewManager;
mPresContext = aPresContext;
mPresShell = aPresShell;
if (ShouldAttachToTopLevel()) {
DetachFromTopLevelWidget();
nsView* rootView = mViewManager->GetRootView();
rootView->AttachToTopLevelWidget(mParentWidget);
mAttachedToParent = true;
}
}
// Fires the "document-shown" event so that interested parties are aware of it.

View File

@ -34,7 +34,8 @@ private:
ImportRule(const ImportRule& aCopy);
~ImportRule();
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ImportRule, nsIStyleRule)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
DECL_STYLE_RULE_INHERIT

View File

@ -370,11 +370,13 @@ ImportRule::~ImportRule()
}
}
NS_IMPL_ADDREF(ImportRule)
NS_IMPL_RELEASE(ImportRule)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ImportRule)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ImportRule)
NS_IMPL_CYCLE_COLLECTION(ImportRule, mMedia, mChildSheet)
// QueryInterface implementation for ImportRule
NS_INTERFACE_MAP_BEGIN(ImportRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImportRule)
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)

View File

@ -156,6 +156,9 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
// Crashes with RoboForm2Go written against old SDK, bug 988311
{ "rf-firefox-22.dll", ALL_VERSIONS },
// Crashes with DesktopTemperature, bug 1046382
{ "dtwxsvc.dll", 0x53153234, DllBlockInfo::USE_TIMESTAMP },
{ nullptr, 0 }
};

View File

@ -22,7 +22,7 @@ class TestSetWindowSize(MarionetteTestCase):
self.marionette.set_window_size(self.start_size['width'], self.start_size['height'])
super(MarionetteTestCase, self).tearDown()
def test_set_window_size(self):
def test_that_we_can_get_and_set_window_size(self):
# event handler
self.marionette.execute_script("""
window.wrappedJSObject.rcvd_event = false;
@ -42,6 +42,11 @@ class TestSetWindowSize(MarionetteTestCase):
self.assertEqual(size['height'], height,
"Window height is %s but should be %s" % (size['height'], height))
def test_that_we_throw_an_error_when_trying_to_set_maximum_size(self):
# valid size
width = self.max_width - 100
height = self.max_height - 100
self.marionette.set_window_size(width, height)
# invalid size (cannot maximize)
with self.assertRaisesRegexp(MarionetteException, "Invalid requested size"):
self.marionette.set_window_size(self.max_width, self.max_height)

View File

@ -168,7 +168,8 @@ class TestTyping(MarionetteTestCase):
# And leave no rubbish/printable keys in the "keyReporter"
self.assertEqual(element.get_attribute("value"), "")
''' Disabled. Reenable in Bug 1068728
def testNumericShiftKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
@ -179,6 +180,7 @@ class TestTyping(MarionetteTestCase):
element.send_keys(numericShiftsEtc)
self.assertEqual(element.get_attribute("value"), numericShiftsEtc)
self.assertTrue(" up: 16" in result.text.strip())
'''
def testLowerCaseAlphaKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
@ -189,6 +191,7 @@ class TestTyping(MarionetteTestCase):
element.send_keys(lowerAlphas)
self.assertEqual(element.get_attribute("value"), lowerAlphas)
''' Disabled. Reenable in Bug 1068735
def testUppercaseAlphaKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
@ -199,7 +202,9 @@ class TestTyping(MarionetteTestCase):
element.send_keys(upperAlphas)
self.assertEqual(element.get_attribute("value"), upperAlphas)
self.assertTrue(" up: 16" in result.text.strip())
'''
''' Disabled. Reenable in Bug 1068726
def testAllPrintableKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
@ -211,7 +216,9 @@ class TestTyping(MarionetteTestCase):
self.assertTrue(element.get_attribute("value"), allPrintable)
self.assertTrue(" up: 16" in result.text.strip())
'''
''' Disabled. Reenable in Bug 1068733
def testSpecialSpaceKeys(self):
test_html = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(test_html)
@ -219,6 +226,7 @@ class TestTyping(MarionetteTestCase):
element = self.marionette.find_element("id", "keyReporter")
element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij")
self.assertEqual(element.get_attribute("value"), "abcd fgh ij")
'''
def testShouldTypeAnInteger(self):
test_html = self.marionette.absolute_url("javascriptPage.html")

View File

@ -42,7 +42,6 @@ disabled = "Bug 896046"
[test_clearing.py]
[test_typing.py]
disabled = "Bug 123456"
[test_log.py]
[test_emulator.py]

View File

@ -1590,193 +1590,9 @@ function sendKeysToElement(msg) {
let command_id = msg.json.command_id;
let el = elementManager.getKnownElement(msg.json.id, curFrame);
if (checkVisible(el)) {
el.focus();
var value = msg.json.value.join("");
let hasShift = null;
let hasCtrl = null;
let hasAlt = null;
let hasMeta = null;
for (var i = 0; i < value.length; i++) {
let upper = value.charAt(i).toUpperCase();
var keyCode = null;
var c = value.charAt(i);
switch (c) {
case '\uE001':
keyCode = "VK_CANCEL";
break;
case '\uE002':
keyCode = "VK_HELP";
break;
case '\uE003':
keyCode = "VK_BACK_SPACE";
break;
case '\uE004':
keyCode = "VK_TAB";
break;
case '\uE005':
keyCode = "VK_CLEAR";
break;
case '\uE006':
case '\uE007':
keyCode = "VK_RETURN";
break;
case '\uE008':
keyCode = "VK_SHIFT";
hasShift = !hasShift;
break;
case '\uE009':
keyCode = "VK_CONTROL";
controlKey = !controlKey;
break;
case '\uE00A':
keyCode = "VK_ALT";
altKey = !altKey;
break;
case '\uE03D':
keyCode = "VK_META";
metaKey = !metaKey;
break;
case '\uE00B':
keyCode = "VK_PAUSE";
break;
case '\uE00C':
keyCode = "VK_ESCAPE";
break;
case '\uE00D':
keyCode = "VK_Space"; // printable
break;
case '\uE00E':
keyCode = "VK_PAGE_UP";
break;
case '\uE00F':
keyCode = "VK_PAGE_DOWN";
break;
case '\uE010':
keyCode = "VK_END";
break;
case '\uE011':
keyCode = "VK_HOME";
break;
case '\uE012':
keyCode = "VK_LEFT";
break;
case '\uE013':
keyCode = "VK_UP";
break;
case '\uE014':
keyCode = "VK_RIGHT";
break;
case '\uE015':
keyCode = "VK_DOWN";
break;
case '\uE016':
keyCode = "VK_INSERT";
break;
case '\uE017':
keyCode = "VK_DELETE";
break;
case '\uE018':
keyCode = "VK_SEMICOLON";
break;
case '\uE019':
keyCode = "VK_EQUALS";
break;
case '\uE01A':
keyCode = "VK_NUMPAD0";
break;
case '\uE01B':
keyCode = "VK_NUMPAD1";
break;
case '\uE01C':
keyCode = "VK_NUMPAD2";
break;
case '\uE01D':
keyCode = "VK_NUMPAD3";
break;
case '\uE01E':
keyCode = "VK_NUMPAD4";
break;
case '\uE01F':
keyCode = "VK_NUMPAD5";
break;
case '\uE020':
keyCode = "VK_NUMPAD6";
break;
case '\uE021':
keyCode = "VK_NUMPAD7";
break;
case '\uE022':
keyCode = "VK_NUMPAD8";
break;
case '\uE023':
keyCode = "VK_NUMPAD9";
break;
case '\uE024':
keyCode = "VK_MULTIPLY";
break;
case '\uE025':
keyCode = "VK_ADD";
break;
case '\uE026':
keyCode = "VK_SEPARATOR";
break;
case '\uE027':
keyCode = "VK_SUBTRACT";
break;
case '\uE028':
keyCode = "VK_DECIMAL";
break;
case '\uE029':
keyCode = "VK_DIVIDE";
break;
case '\uE031':
keyCode = "VK_F1";
break;
case '\uE032':
keyCode = "VK_F2";
break;
case '\uE033':
keyCode = "VK_F3";
break;
case '\uE034':
keyCode = "VK_F4";
break;
case '\uE035':
keyCode = "VK_F5";
break;
case '\uE036':
keyCode = "VK_F6";
break;
case '\uE037':
keyCode = "VK_F7";
break;
case '\uE038':
keyCode = "VK_F8";
break;
case '\uE039':
keyCode = "VK_F9";
break;
case '\uE03A':
keyCode = "VK_F10";
break;
case '\uE03B':
keyCode = "VK_F11";
break;
case '\uE03C':
keyCode = "VK_F12";
break;
}
hasShift = value.charAt(i) == upper;
utils.synthesizeKey(keyCode || value[i],
{ shiftKey: hasShift, ctrlKey: hasCtrl, altKey: hasAlt, metaKey: hasMeta },
curFrame);
};
sendOk(command_id);
}
else {
sendError("Element is not visible", 11, null, command_id)
}
let keysToSend = msg.json.value;
utils.sendKeysToElement(curFrame, el, keysToSend, sendOk, sendError, command_id);
}
/**

View File

@ -16,365 +16,200 @@
* limitations under the License.
*/
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
var type = function(doc, element, text, releaseModifiers,
opt_keysState) {
let utils = {};
loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils);
loader.loadSubScript("chrome://marionette/content/ChromeUtils.js", utils);
var currentTextLength = element.value ? element.value.length : 0;
element.selectionStart = currentTextLength;
element.selectionEnd = currentTextLength;
// For consistency between native and synthesized events, convert common
// escape sequences to their Key enum aliases.
text = text.replace(new RegExp('\b', 'g'), '\uE003'). // DOM_VK_BACK_SPACE
replace(/\t/g, '\uE004'). // DOM_VK_TAB
replace(/(\r\n|\n|\r)/g, '\uE006'); // DOM_VK_RETURN
var controlKey = false;
var shiftKey = false;
var altKey = false;
var metaKey = false;
if (opt_keysState) {
controlKey = opt_keysState.control;
shiftKey = opt_keysState.shiftKey;
altKey = opt_keysState.alt;
metaKey = opt_keysState.meta;
}
shiftCount = 0;
var upper = text.toUpperCase();
for (var i = 0; i < text.length; i++) {
var c = text.charAt(i);
// NULL key: reset modifier key states, and continue
if (c == '\uE000') {
if (controlKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey = false, shiftKey, altKey, metaKey, false);
function sendKeysToElement (document, element, keysToSend, successCallback, errorCallback, command_id) {
if (checkVisible(element)) {
element.focus();
var value = keysToSend.join("");
let hasShift = null;
let hasCtrl = null;
let hasAlt = null;
let hasMeta = null;
for (var i = 0; i < value.length; i++) {
let upper = value.charAt(i).toUpperCase();
var keyCode = null;
var c = value.charAt(i);
switch (c) {
case '\uE001':
keyCode = "VK_CANCEL";
break;
case '\uE002':
keyCode = "VK_HELP";
break;
case '\uE003':
keyCode = "VK_BACK_SPACE";
break;
case '\uE004':
keyCode = "VK_TAB";
break;
case '\uE005':
keyCode = "VK_CLEAR";
break;
case '\uE006':
case '\uE007':
keyCode = "VK_RETURN";
break;
case '\uE008':
keyCode = "VK_SHIFT";
hasShift = !hasShift;
break;
case '\uE009':
keyCode = "VK_CONTROL";
controlKey = !controlKey;
break;
case '\uE00A':
keyCode = "VK_ALT";
altKey = !altKey;
break;
case '\uE03D':
keyCode = "VK_META";
metaKey = !metaKey;
break;
case '\uE00B':
keyCode = "VK_PAUSE";
break;
case '\uE00C':
keyCode = "VK_ESCAPE";
break;
case '\uE00D':
keyCode = "VK_SPACE"; // printable
break;
case '\uE00E':
keyCode = "VK_PAGE_UP";
break;
case '\uE00F':
keyCode = "VK_PAGE_DOWN";
break;
case '\uE010':
keyCode = "VK_END";
break;
case '\uE011':
keyCode = "VK_HOME";
break;
case '\uE012':
keyCode = "VK_LEFT";
break;
case '\uE013':
keyCode = "VK_UP";
break;
case '\uE014':
keyCode = "VK_RIGHT";
break;
case '\uE015':
keyCode = "VK_DOWN";
break;
case '\uE016':
keyCode = "VK_INSERT";
break;
case '\uE017':
keyCode = "VK_DELETE";
break;
case '\uE018':
keyCode = "VK_SEMICOLON";
break;
case '\uE019':
keyCode = "VK_EQUALS";
break;
case '\uE01A':
keyCode = "VK_NUMPAD0";
break;
case '\uE01B':
keyCode = "VK_NUMPAD1";
break;
case '\uE01C':
keyCode = "VK_NUMPAD2";
break;
case '\uE01D':
keyCode = "VK_NUMPAD3";
break;
case '\uE01E':
keyCode = "VK_NUMPAD4";
break;
case '\uE01F':
keyCode = "VK_NUMPAD5";
break;
case '\uE020':
keyCode = "VK_NUMPAD6";
break;
case '\uE021':
keyCode = "VK_NUMPAD7";
break;
case '\uE022':
keyCode = "VK_NUMPAD8";
break;
case '\uE023':
keyCode = "VK_NUMPAD9";
break;
case '\uE024':
keyCode = "VK_MULTIPLY";
break;
case '\uE025':
keyCode = "VK_ADD";
break;
case '\uE026':
keyCode = "VK_SEPARATOR";
break;
case '\uE027':
keyCode = "VK_SUBTRACT";
break;
case '\uE028':
keyCode = "VK_DECIMAL";
break;
case '\uE029':
keyCode = "VK_DIVIDE";
break;
case '\uE031':
keyCode = "VK_F1";
break;
case '\uE032':
keyCode = "VK_F2";
break;
case '\uE033':
keyCode = "VK_F3";
break;
case '\uE034':
keyCode = "VK_F4";
break;
case '\uE035':
keyCode = "VK_F5";
break;
case '\uE036':
keyCode = "VK_F6";
break;
case '\uE037':
keyCode = "VK_F7";
break;
case '\uE038':
keyCode = "VK_F8";
break;
case '\uE039':
keyCode = "VK_F9";
break;
case '\uE03A':
keyCode = "VK_F10";
break;
case '\uE03B':
keyCode = "VK_F11";
break;
case '\uE03C':
keyCode = "VK_F12";
break;
}
if (shiftKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey = false, altKey, metaKey, false);
}
if (altKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey, altKey = false, metaKey, false);
}
if (metaKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey, altKey, metaKey = false, false);
}
continue;
}
// otherwise decode keyCode, charCode, modifiers ...
var modifierEvent = "";
var charCode = 0;
var keyCode = 0;
if (c == '\uE001') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CANCEL;
} else if (c == '\uE002') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_HELP;
} else if (c == '\uE003') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_SPACE;
} else if (c == '\uE004') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_TAB;
} else if (c == '\uE005') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CLEAR;
} else if (c == '\uE006' || c == '\uE007') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_RETURN;
} else if (c == '\uE008') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
shiftKey = !shiftKey;
modifierEvent = shiftKey ? "keydown" : "keyup";
} else if (c == '\uE009') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
controlKey = !controlKey;
modifierEvent = controlKey ? "keydown" : "keyup";
} else if (c == '\uE00A') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
altKey = !altKey;
modifierEvent = altKey ? "keydown" : "keyup";
} else if (c == '\uE03D') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
metaKey = !metaKey;
modifierEvent = metaKey ? "keydown" : "keyup";
} else if (c == '\uE00B') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAUSE;
} else if (c == '\uE00C') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ESCAPE;
} else if (c == '\uE00D') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SPACE;
keyCode = charCode = ' '.charCodeAt(0); // printable
} else if (c == '\uE00E') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAGE_UP;
} else if (c == '\uE00F') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN;
} else if (c == '\uE010') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_END;
} else if (c == '\uE011') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_HOME;
} else if (c == '\uE012') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_LEFT;
} else if (c == '\uE013') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_UP;
} else if (c == '\uE014') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_RIGHT;
} else if (c == '\uE015') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DOWN;
} else if (c == '\uE016') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_INSERT;
} else if (c == '\uE017') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DELETE;
} else if (c == '\uE018') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SEMICOLON;
charCode = ';'.charCodeAt(0);
} else if (c == '\uE019') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_EQUALS;
charCode = '='.charCodeAt(0);
} else if (c == '\uE01A') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD0;
charCode = '0'.charCodeAt(0);
} else if (c == '\uE01B') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD1;
charCode = '1'.charCodeAt(0);
} else if (c == '\uE01C') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD2;
charCode = '2'.charCodeAt(0);
} else if (c == '\uE01D') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD3;
charCode = '3'.charCodeAt(0);
} else if (c == '\uE01E') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD4;
charCode = '4'.charCodeAt(0);
} else if (c == '\uE01F') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD5;
charCode = '5'.charCodeAt(0);
} else if (c == '\uE020') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD6;
charCode = '6'.charCodeAt(0);
} else if (c == '\uE021') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD7;
charCode = '7'.charCodeAt(0);
} else if (c == '\uE022') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD8;
charCode = '8'.charCodeAt(0);
} else if (c == '\uE023') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD9;
charCode = '9'.charCodeAt(0);
} else if (c == '\uE024') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_MULTIPLY;
charCode = '*'.charCodeAt(0);
} else if (c == '\uE025') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ADD;
charCode = '+'.charCodeAt(0);
} else if (c == '\uE026') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SEPARATOR;
charCode = ','.charCodeAt(0);
} else if (c == '\uE027') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SUBTRACT;
charCode = '-'.charCodeAt(0);
} else if (c == '\uE028') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DECIMAL;
charCode = '.'.charCodeAt(0);
} else if (c == '\uE029') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DIVIDE;
charCode = '/'.charCodeAt(0);
} else if (c == '\uE031') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F1;
} else if (c == '\uE032') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F2;
} else if (c == '\uE033') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F3;
} else if (c == '\uE034') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F4;
} else if (c == '\uE035') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F5;
} else if (c == '\uE036') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F6;
} else if (c == '\uE037') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F7;
} else if (c == '\uE038') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F8;
} else if (c == '\uE039') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F9;
} else if (c == '\uE03A') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F10;
} else if (c == '\uE03B') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F11;
} else if (c == '\uE03C') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F12;
} else if (c == ',' || c == '<') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_COMMA;
charCode = c.charCodeAt(0);
} else if (c == '.' || c == '>') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PERIOD;
charCode = c.charCodeAt(0);
} else if (c == '/' || c == '?') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SLASH;
charCode = text.charCodeAt(i);
} else if (c == '`' || c == '~') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_QUOTE;
charCode = c.charCodeAt(0);
} else if (c == '{' || c == '[') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET;
charCode = c.charCodeAt(0);
} else if (c == '\\' || c == '|') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_SLASH;
charCode = c.charCodeAt(0);
} else if (c == '}' || c == ']') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET;
charCode = c.charCodeAt(0);
} else if (c == '\'' || c == '"') {
keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_QUOTE;
charCode = c.charCodeAt(0);
} else {
keyCode = upper.charCodeAt(i);
charCode = text.charCodeAt(i);
}
// generate modifier key event if needed, and continue
if (modifierEvent) {
keyEvent(doc, element, modifierEvent, keyCode, 0,
controlKey, shiftKey, altKey, metaKey, false);
continue;
}
// otherwise, shift down if needed
var needsShift = false;
if (charCode) {
needsShift = /[A-Z\!\$\^\*\(\)\+\{\}\:\?\|~@#%&_"<>]/.test(c);
}
if (needsShift && !shiftKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
keyEvent(doc, element, "keydown", kCode, 0,
controlKey, true, altKey, metaKey, false);
shiftCount += 1;
}
// generate key[down/press/up] for key
var pressCode = keyCode;
if (charCode >= 32 && charCode < 127) {
pressCode = 0;
if (!needsShift && shiftKey && charCode > 32) {
// If typing a lowercase character key and the shiftKey is down, the
// charCode should be mapped to the shifted key value. This assumes
// a default 104 international keyboard layout.
if (charCode >= 97 && charCode <= 122) {
charCode = charCode + 65 - 97; // [a-z] -> [A-Z]
} else {
var mapFrom = '`1234567890-=[]\\;\',./';
var mapTo = '~!@#$%^&*()_+{}|:"<>?';
var value = String.fromCharCode(charCode).
replace(/([\[\\\.])/g, '\\$1');
var index = mapFrom.search(value);
if (index >= 0) {
charCode = mapTo.charCodeAt(index);
}
}
}
}
var accepted =
keyEvent(doc, element, "keydown", keyCode, 0,
controlKey, needsShift || shiftKey, altKey, metaKey, false);
keyEvent(doc, element, "keypress", pressCode, charCode,
controlKey, needsShift || shiftKey, altKey, metaKey, !accepted);
keyEvent(doc, element, "keyup", keyCode, 0,
controlKey, needsShift || shiftKey, altKey, metaKey, false);
// shift up if needed
if (needsShift && !shiftKey) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, false, altKey, metaKey, false);
hasShift = value.charAt(i) == upper;
utils.synthesizeKey(keyCode || value[i],
{ shiftKey: hasShift, ctrlKey: hasCtrl, altKey: hasAlt, metaKey: hasMeta },
document);
}
successCallback(command_id);
}
// exit cleanup: keyup active modifier keys
if (controlKey && releaseModifiers) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey = false, shiftKey, altKey, metaKey, false);
else {
errorCallback("Element is not visible", 11, null, command_id);
}
if (shiftKey && releaseModifiers) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey = false, altKey, metaKey, false);
}
if (altKey && releaseModifiers) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey, altKey = false, metaKey, false);
}
if (metaKey && releaseModifiers) {
var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
keyEvent(doc, element, "keyup", kCode, 0,
controlKey, shiftKey, altKey, metaKey = false, false);
}
return {
shiftKey: shiftKey,
alt: altKey,
meta: metaKey,
control: controlKey
};
};
var keyEvent = function(doc, element, type, keyCode, charCode,
controlState, shiftState, altState, metaState,
shouldPreventDefault) {
var preventDefault = shouldPreventDefault == undefined ? false
: shouldPreventDefault;
var keyboardEvent = doc.createEvent("KeyEvents");
var currentView = doc.defaultView;
keyboardEvent.initKeyEvent(
type, // in DOMString typeArg,
true, // in boolean canBubbleArg
true, // in boolean cancelableArg
currentView, // in nsIDOMAbstractView viewArg
controlState, // in boolean ctrlKeyArg
altState, // in boolean altKeyArg
shiftState, // in boolean shiftKeyArg
metaState, // in boolean metaKeyArg
keyCode, // in unsigned long keyCodeArg
charCode); // in unsigned long charCodeArg
if (preventDefault) {
keyboardEvent.preventDefault();
}
var win = doc.defaultView;
var domUtil = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
return domUtil.dispatchDOMEventViaPresShell(element, keyboardEvent, true);
};
};

View File

@ -2420,8 +2420,8 @@ MarionetteServerConnection.prototype = {
setWindowSize: function MDA_setWindowSize(aRequest) {
this.command_id = this.getCommandId();
if (appName == "B2G") {
this.sendError("Not supported on B2G", 405, null, this.command_id);
if (appName !== "Firefox") {
this.sendError("Not supported on mobile", 405, null, this.command_id);
return;
}

View File

@ -821,20 +821,41 @@ function makeDReportMap(aJSONReports)
assert(jr.amount !== undefined, "Missing amount");
assert(jr.description !== undefined, "Missing description");
// Strip out some non-deterministic stuff that prevents clean diffs --
// e.g. PIDs, addresses, null principal UUIDs. (Note that we don't strip
// out all UUIDs because some of them -- such as those used by add-ons --
// are deterministic.)
// Strip out some non-deterministic stuff that prevents clean diffs.
// Ideally the memory reports themselves would contain information about
// which parts of the the process and path need to be stripped -- saving us
// from hardwiring knowledge of specific reporters here -- but we have no
// mechanism for that. (Any future redesign of how memory reporters work
// should include such a mechanism.)
// Strip PIDs:
// - pid 123
// - pid=123
let pidRegex = /pid([ =])\d+/g;
let pidSubst = "pid$1NNN";
let strippedProcess = jr.process.replace(pidRegex, pidSubst);
let strippedPath = jr.path.replace(/0x[0-9A-Fa-f]+/g, "0xNNN");
strippedPath = strippedPath.replace(pidRegex, pidSubst);
strippedPath = strippedPath.replace(
let process = jr.process.replace(pidRegex, pidSubst);
let path = jr.path.replace(pidRegex, pidSubst);
// Strip addresses:
// - .../js-zone(0x12345678)/...
// - .../zone(0x12345678)/...
// - .../worker(<URL>, 0x12345678)/...
path = path.replace(/zone\(0x[0-9A-Fa-f]+\)\//, "zone(0xNNN)/");
path = path.replace(/\/worker\((.+), 0x[0-9A-Fa-f]+\)\//,
"/worker($1, 0xNNN)/");
// Strip top window IDs:
// - explicit/window-objects/top(<URL>, id=123)/...
path = path.replace(/^(explicit\/window-objects\/top\(.*, id=)\d+\)/,
"$1NNN)");
// Strip null principal UUIDs (but not other UUIDs, because they may be
// deterministic, such as those used by add-ons).
path = path.replace(
/moz-nullprincipal:{........-....-....-....-............}/g,
"moz-nullprincipal:{NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN}");
let processPath = strippedProcess + kProcessPathSep + strippedPath;
let processPath = process + kProcessPathSep + path;
let rOld = dreportMap[processPath];
if (rOld === undefined) {
dreportMap[processPath] =

View File

@ -20,7 +20,13 @@
{"process": "P", "path": "a/c/g", "kind": 2, "units": 0, "amount": 3000000, "description": "Desc."},
{"process": "P", "path": "a/h", "kind": 2, "units": 0, "amount": 1000, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "z-moz-nullprincipal:{85e250f3-57ae-46c4-a11e-4176dd39d9c5} 0x1234-blah(0x2345) pid 123 pid=45678", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p1 (pid 123)", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p2 (blah, pid=123)", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p3/zone(0x1234)/p3", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p4/js-zone(0x1234)/p4", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p5/worker(foo.com, 0x1234)/p5", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "explicit/window-objects/top(bar.com, id=123)/...", "kind": 0, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p6/z-moz-nullprincipal:{85e250f3-57ae-46c4-a11e-4176dd39d9c5}/p6", "kind": 2, "units": 0, "amount": 33, "description": "Desc."},
{"process": "P3", "path": "p3", "kind": 2, "units": 0, "amount": 55, "description": "Desc."},

View File

@ -21,7 +21,13 @@
{"process": "P", "path": "a/c/g", "kind": 2, "units": 0, "amount": 3001000, "description": "Desc."},
{"process": "P", "path": "a/h", "kind": 2, "units": 0, "amount": 2000, "description": "Desc."},
{"process": "P2 (pid 33)", "path": "z-moz-nullprincipal:{161effaa-c1f7-4010-a08e-e7c9aea01aed} 0x5678-blah(0x6789) pid 456 pid=7890", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p1 (pid 456)", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p2 (blah, pid=456)", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p3/zone(0x5678)/p3", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p4/js-zone(0x5678)/p4", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p5/worker(foo.com, 0x5678)/p5", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "explicit/window-objects/top(bar.com, id=456)/...", "kind": 0, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P2 (pid 22)", "path": "p6/z-moz-nullprincipal:{161effaa-c1f7-4010-a08e-e7c9aea01aed}/p6", "kind": 2, "units": 0, "amount": 44, "description": "Desc."},
{"process": "P4", "path": "p4", "kind": 2, "units": 0, "amount": 66, "description": "Desc."},

View File

@ -305,9 +305,29 @@ Other Measurements\n\
\n\
End of P\n\
P2 (pid NNN)\n\
\n\
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
Explicit Allocations\n\
\n\
0.00 MB (100.0%) -- explicit\n\
└──0.00 MB (100.0%) ── window-objects/top(bar.com, id=NNN)/...\n\
\n\
Other Measurements\n\
\n\
0.00 MB ── z-moz-nullprincipal:{NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN} 0xNNN-blah(0xNNN) pid NNN pid=NNN\n\
0.00 MB (100.0%) -- p3\n\
└──0.00 MB (100.0%) ── zone(0xNNN)/p3\n\
\n\
0.00 MB (100.0%) -- p4\n\
└──0.00 MB (100.0%) ── js-zone(0xNNN)/p4\n\
\n\
0.00 MB (100.0%) -- p5\n\
└──0.00 MB (100.0%) ── worker(foo.com, 0xNNN)/p5\n\
\n\
0.00 MB (100.0%) -- p6\n\
└──0.00 MB (100.0%) ── z-moz-nullprincipal:{NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN}/p6\n\
\n\
0.00 MB ── p1 (pid NNN)\n\
0.00 MB ── p2 (blah, pid=NNN)\n\
\n\
End of P2 (pid NNN)\n\
P3\n\
@ -380,9 +400,29 @@ Other Measurements\n\
\n\
End of P\n\
P2 (pid NNN)\n\
\n\
WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
Explicit Allocations\n\
\n\
11 B (100.0%) -- explicit\n\
└──11 B (100.0%) ── window-objects/top(bar.com, id=NNN)/...\n\
\n\
Other Measurements\n\
\n\
11 B ── z-moz-nullprincipal:{NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN} 0xNNN-blah(0xNNN) pid NNN pid=NNN\n\
11 B (100.0%) -- p3\n\
└──11 B (100.0%) ── zone(0xNNN)/p3\n\
\n\
11 B (100.0%) -- p4\n\
└──11 B (100.0%) ── js-zone(0xNNN)/p4\n\
\n\
11 B (100.0%) -- p5\n\
└──11 B (100.0%) ── worker(foo.com, 0xNNN)/p5\n\
\n\
11 B (100.0%) -- p6\n\
└──11 B (100.0%) ── z-moz-nullprincipal:{NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN}/p6\n\
\n\
11 B ── p1 (pid NNN)\n\
11 B ── p2 (blah, pid=NNN)\n\
\n\
End of P2 (pid NNN)\n\
P3\n\

View File

@ -543,6 +543,8 @@ private:
aName.AppendLiteral("/extensions");
} else if (dirname.Find("/fontconfig") != -1) {
aName.AppendLiteral("/fontconfig");
} else {
aName.AppendLiteral("/misc");
}
aTag = aName;
aName.Append('/');