Merge inbound to m-c

This commit is contained in:
Wes Kocher 2013-11-04 21:09:17 -08:00
commit e400a12724
118 changed files with 1766 additions and 250 deletions

View File

@ -259,7 +259,7 @@ endif
ifdef MOZ_PSEUDO_DERECURSE
# Interdependencies for parallel export.
js/xpconnect/src/export: dom/bindings/export
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
accessible/src/xpcom/export: xpcom/xpidl/export
js/src/export: mfbt/export
ifdef ENABLE_CLANG_PLUGIN

View File

@ -18,8 +18,7 @@ endif
xpcAccEvents.cpp: $(srcdir)/AccEvents.conf \
$(srcdir)/AccEventGen.py \
$(LIBXUL_DIST)/sdk/bin/header.py \
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
$(DEPTH)/js/src/js-confdefs.h
$(LIBXUL_DIST)/sdk/bin/xpidl.py
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(LIBXUL_DIST)/sdk/bin \
$(srcdir)/AccEventGen.py \

View File

@ -574,7 +574,11 @@ pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
pref("browser.gesture.tap", "cmd_fullZoomReset");
#ifndef RELEASE_BUILD
pref("browser.snapshots.limit", 5);
#else
pref("browser.snapshots.limit", 0);
#endif
// 0: Nothing happens
// 1: Scrolling contents

View File

@ -7,8 +7,6 @@ include $(topsrcdir)/config/config.mk
abs_srcdir = $(abspath $(srcdir))
CHROME_DEPS += $(abs_srcdir)/content/overrides/app-license.html
include $(topsrcdir)/config/rules.mk
PRE_RELEASE_SUFFIX := ""

View File

@ -139,7 +139,6 @@
footertype="promobox"
orient="vertical"
ignorekeys="true"
consumeoutsideclicks="true"
hidden="true"
onpopupshown="StarUI.panelShown(event);"
aria-labelledby="editBookmarkPanelTitle">
@ -188,7 +187,6 @@
<panel id="UITourTooltip"
type="arrow"
hidden="true"
consumeoutsideclicks="false"
noautofocus="true"
align="start"
orient="vertical"
@ -203,7 +201,6 @@
<panel id="socialActivatedNotification"
type="arrow"
hidden="true"
consumeoutsideclicks="true"
align="start"
orient="horizontal"
role="alert">
@ -234,7 +231,6 @@
orient="horizontal"
onpopupshowing="SocialShare.onShowing()"
onpopuphidden="SocialShare.onHidden()"
consumeoutsideclicks="true"
hidden="true">
<vbox class="social-share-toolbar">
<vbox id="social-share-provider-buttons" flex="1"/>
@ -255,7 +251,6 @@
hidden="true"
flip="slide"
rolluponmousewheel="true"
consumeoutsideclicks="false"
noautofocus="true"
position="topcenter topright"/>
@ -313,7 +308,6 @@
type="arrow"
hidden="true"
noautofocus="true"
consumeoutsideclicks="true"
onpopupshown="if (event.target == this)
gIdentityHandler.onPopupShown(event);"
orient="vertical"

View File

@ -46,7 +46,6 @@
type="arrow"
orient="vertical"
level="top"
consumeoutsideclicks="true"
onpopupshown="DownloadsPanel.onPopupShown(event);"
onpopuphidden="DownloadsPanel.onPopupHidden(event);">
<!-- The following popup menu should be a child of the panel element,

View File

@ -11,7 +11,6 @@ ifdef MOZILLA_OFFICIAL
DEFINES += -DMOZILLA_OFFICIAL
endif
GRE_MILESTONE := $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)

View File

@ -95,6 +95,7 @@ oddly_ordered_inclnames = set([
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
'jsautokw.h', # Included in the body of frontend/TokenStream.h
'jswin.h', # Must be #included before <psapi.h>
'machine/endian.h', # Must be included after <sys/types.h> on BSD
'winbase.h', # Must precede other system headers(?)
'windef.h' # Must precede other system headers(?)
])

View File

@ -195,9 +195,8 @@ MOZ_PSEUDO_DERECURSE :=
endif
endif
# Disable MOZ_PSEUDO_DERECURSE on the second PGO pass until it's widely
# tested.
ifdef MOZ_PROFILE_USE
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
MOZ_PSEUDO_DERECURSE :=
endif

View File

@ -1331,7 +1331,7 @@ endif
endif
endif
libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
libs realchrome:: $(FINAL_TARGET)/chrome
$(call py_action,jar_maker,\
$(QUIET) -j $(FINAL_TARGET)/chrome \
$(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \

View File

@ -38,6 +38,7 @@
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsDisplayList.h"
#include "nsFocusManager.h"
#include "nsTArray.h"
@ -1712,6 +1713,90 @@ CanvasRenderingContext2D::Stroke()
Redraw();
}
void CanvasRenderingContext2D::DrawSystemFocusRing(mozilla::dom::Element& aElement)
{
EnsureUserSpacePath();
if (!mPath) {
return;
}
if(DrawCustomFocusRing(aElement)) {
Save();
// set state to conforming focus state
ContextState& state = CurrentState();
state.globalAlpha = 1.0;
state.shadowBlur = 0;
state.shadowOffset.x = 0;
state.shadowOffset.y = 0;
state.op = mozilla::gfx::OP_OVER;
state.lineCap = CAP_BUTT;
state.lineJoin = mozilla::gfx::JOIN_MITER_OR_BEVEL;
state.lineWidth = 1;
CurrentState().dash.Clear();
// color and style of the rings is the same as for image maps
// set the background focus color
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(255, 255, 255, 255));
// draw the focus ring
Stroke();
// set dashing for foreground
FallibleTArray<mozilla::gfx::Float>& dash = CurrentState().dash;
dash.AppendElement(1);
dash.AppendElement(1);
// set the foreground focus color
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(0,0,0, 255));
// draw the focus ring
Stroke();
Restore();
}
}
bool CanvasRenderingContext2D::DrawCustomFocusRing(mozilla::dom::Element& aElement)
{
EnsureUserSpacePath();
HTMLCanvasElement* canvas = GetCanvas();
if (!canvas|| !nsContentUtils::ContentIsDescendantOf(&aElement, canvas)) {
return false;
}
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
// check that the element i focused
nsCOMPtr<nsIDOMElement> focusedElement;
fm->GetFocusedElement(getter_AddRefs(focusedElement));
if (SameCOMIdentity(aElement.AsDOMNode(), focusedElement)) {
// get the bounds of the current path
mgfx::Rect bounds;
bounds = mPath->GetBounds(mTarget->GetTransform());
// and set them as the accessible area
nsRect rect(canvas->ClientLeft() + bounds.x, canvas->ClientTop() + bounds.y,
bounds.width, bounds.height);
rect.x *= AppUnitsPerCSSPixel();
rect.y *= AppUnitsPerCSSPixel();
rect.width *= AppUnitsPerCSSPixel();
rect.height *= AppUnitsPerCSSPixel();
nsIFrame* frame = aElement.GetPrimaryFrame();
if(frame) {
frame->SetRect(rect);
}
return true;
}
}
return false;
}
void
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
{

View File

@ -171,6 +171,8 @@ public:
void BeginPath();
void Fill(const CanvasWindingRule& winding);
void Stroke();
void DrawSystemFocusRing(mozilla::dom::Element& element);
bool DrawCustomFocusRing(mozilla::dom::Element& element);
void Clip(const CanvasWindingRule& winding);
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
bool IsPointInStroke(double x, double y);

View File

@ -890,6 +890,7 @@ protected:
// -------------------------------------------------------------------------
// WebGL extensions (implemented in WebGLContextExtensions.cpp)
enum WebGLExtensionID {
EXT_sRGB,
EXT_texture_filter_anisotropic,
OES_element_index_uint,
OES_standard_derivatives,
@ -952,7 +953,7 @@ protected:
bool ValidateGLSLVariableName(const nsAString& name, const char *info);
bool ValidateGLSLCharacter(PRUnichar c);
bool ValidateGLSLString(const nsAString& string, const char *info);
bool ValidateTexImage2DFormat(GLenum format, const char* info);
bool ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info);
bool ValidateCompressedTextureSize(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, uint32_t byteLength, const char* info);
bool ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, GLsizei height, const char* info);

View File

@ -17,6 +17,7 @@ using namespace mozilla::gl;
// must match WebGLContext::WebGLExtensionID
static const char *sExtensionNames[] = {
"EXT_sRGB",
"EXT_texture_filter_anisotropic",
"OES_element_index_uint",
"OES_standard_derivatives",
@ -113,6 +114,8 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
gl->IsExtensionSupported(GLContext::ANGLE_depth_texture);
case ANGLE_instanced_arrays:
return WebGLExtensionInstancedArrays::IsSupported(this);
case EXT_sRGB:
return WebGLExtensionSRGB::IsSupported(this);
default:
// For warnings-as-errors.
break;
@ -257,6 +260,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
case ANGLE_instanced_arrays:
obj = new WebGLExtensionInstancedArrays(this);
break;
case EXT_sRGB:
obj = new WebGLExtensionSRGB(this);
break;
default:
MOZ_ASSERT(false, "should not get there.");
}

View File

@ -584,7 +584,7 @@ WebGLContext::CopyTexImage2D(GLenum target,
sizeMayChange = width != imageInfo.Width() ||
height != imageInfo.Height() ||
internalformat != imageInfo.Format() ||
internalformat != imageInfo.InternalFormat() ||
type != imageInfo.Type();
}
@ -661,7 +661,7 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
if (yoffset + height > texHeight || yoffset + height < 0)
return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
GLenum format = imageInfo.Format();
GLenum format = imageInfo.InternalFormat();
bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_LUMINANCE_ALPHA;
@ -1045,7 +1045,7 @@ WebGLContext::BindFakeBlackTexturesHelper(
}
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().Format());
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().InternalFormat());
ScopedDeletePtr<FakeBlackTexture>&
blackTexturePtr = alpha
? transparentTextureScopedPtr
@ -1205,7 +1205,7 @@ WebGLContext::GenerateMipmap(GLenum target)
if (!tex->IsFirstImagePowerOfTwo())
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
GLenum format = tex->ImageInfoAt(imageTarget, 0).Format();
GLenum format = tex->ImageInfoAt(imageTarget, 0).InternalFormat();
if (IsTextureFormatCompressed(format))
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
@ -1415,6 +1415,15 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
if (fba.Renderbuffer()) {
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
if (IsExtensionEnabled(EXT_sRGB)) {
const GLenum internalFormat = fba.Renderbuffer()->InternalFormat();
return (internalFormat == LOCAL_GL_SRGB_EXT ||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT) ?
JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
}
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER));
@ -1429,6 +1438,16 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
}
} else if (fba.Texture()) {
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
if (IsExtensionEnabled(EXT_sRGB)) {
const GLenum internalFormat =
fba.Texture()->ImageInfoBase().InternalFormat();
return (internalFormat == LOCAL_GL_SRGB_EXT ||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT) ?
JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
}
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::NumberValue(uint32_t(LOCAL_GL_TEXTURE));
@ -2493,6 +2512,8 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
// We emulate this in WebGLRenderbuffer if we don't have the requisite extension.
internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
break;
case LOCAL_GL_SRGB8_ALPHA8_EXT:
break;
default:
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
}
@ -3679,7 +3700,7 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target,
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
sizeMayChange = width != imageInfo.Width() ||
height != imageInfo.Height() ||
format != imageInfo.Format() ||
format != imageInfo.InternalFormat() ||
type != imageInfo.Type();
}
@ -3708,18 +3729,8 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
return;
}
switch (format) {
case LOCAL_GL_RGB:
case LOCAL_GL_RGBA:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
case LOCAL_GL_LUMINANCE_ALPHA:
case LOCAL_GL_DEPTH_COMPONENT:
case LOCAL_GL_DEPTH_STENCIL:
break;
default:
return ErrorInvalidEnumInfo("texImage2D: internal format", internalformat);
}
if (!ValidateTexImage2DFormat(format, "texImage2D: format"))
return;
if (format != internalformat)
return ErrorInvalidOperation("texImage2D: format does not match internalformat");
@ -3791,6 +3802,23 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
// format == internalformat, as checked above and as required by ES.
internalformat = InternalFormatForFormatAndType(format, type, gl->IsGLES2());
// Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
// requires that format == internalformat, but GL will fail in this case.
// GL requires:
// format -> internalformat
// GL_RGB GL_SRGB_EXT
// GL_RGBA GL_SRGB_ALPHA_EXT
if (!gl->IsGLES2()) {
switch (internalformat) {
case LOCAL_GL_SRGB_EXT:
format = LOCAL_GL_RGB;
break;
case LOCAL_GL_SRGB_ALPHA_EXT:
format = LOCAL_GL_RGBA;
break;
}
}
GLenum error = LOCAL_GL_NO_ERROR;
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::NoImageData;
@ -3839,7 +3867,7 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
// have NoImageData at this point.
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
tex->SetImageInfo(target, level, width, height, format, type, imageInfoStatusIfSuccess);
tex->SetImageInfo(target, level, width, height, internalformat, type, imageInfoStatusIfSuccess);
ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
}
@ -3959,7 +3987,7 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
// Require the format and type in texSubImage2D to match that of the existing texture as created by texImage2D
if (imageInfo.Format() != format || imageInfo.Type() != type)
if (imageInfo.InternalFormat() != format || imageInfo.Type() != type)
return ErrorInvalidOperation("texSubImage2D: format or type doesn't match the existing texture");
if (imageInfo.HasUninitializedImageData()) {
@ -4157,8 +4185,10 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum format, GLenum type)
if (type == LOCAL_GL_UNSIGNED_BYTE) {
switch (format) {
case LOCAL_GL_RGBA:
case LOCAL_GL_SRGB_ALPHA_EXT:
return WebGLTexelFormat::RGBA8;
case LOCAL_GL_RGB:
case LOCAL_GL_SRGB_EXT:
return WebGLTexelFormat::RGB8;
case LOCAL_GL_ALPHA:
return WebGLTexelFormat::A8;

View File

@ -300,6 +300,32 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
return true;
}
bool WebGLContext::ValidateTexImage2DFormat(GLenum format, const char* info)
{
if (IsExtensionEnabled(EXT_sRGB)) {
switch (format) {
case LOCAL_GL_SRGB_EXT:
case LOCAL_GL_SRGB_ALPHA_EXT:
return true;
}
}
switch (format) {
case LOCAL_GL_RGB:
case LOCAL_GL_RGBA:
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
case LOCAL_GL_LUMINANCE_ALPHA:
case LOCAL_GL_DEPTH_COMPONENT:
case LOCAL_GL_DEPTH_STENCIL:
return true;
break;
}
ErrorInvalidEnumInfo(info, format);
return false;
}
bool WebGLContext::ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height,
const char* info)
{
@ -464,8 +490,10 @@ uint32_t WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
case LOCAL_GL_LUMINANCE_ALPHA:
return 2 * multiplier;
case LOCAL_GL_RGB:
case LOCAL_GL_SRGB_EXT:
return 3 * multiplier;
case LOCAL_GL_RGBA:
case LOCAL_GL_SRGB_ALPHA_EXT:
return 4 * multiplier;
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
@ -562,9 +590,11 @@ bool WebGLContext::ValidateTexFormatAndType(GLenum format, GLenum type, int jsAr
*texelSize = 2 * texMultiplier;
return true;
case LOCAL_GL_RGB:
case LOCAL_GL_SRGB_EXT:
*texelSize = 3 * texMultiplier;
return true;
case LOCAL_GL_RGBA:
case LOCAL_GL_SRGB_ALPHA_EXT:
*texelSize = 4 * texMultiplier;
return true;
default:

View File

@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
using namespace mozilla;
WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext* context)
: WebGLExtensionBase(context)
{
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionSRGB: "
"sRGB is unsupported.");
gl::GLContext* gl = context->GL();
if (!gl->IsGLES()) {
// Desktop OpenGL requires the following to be enabled to support
// sRGB operations on framebuffers
gl->MakeCurrent();
gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT);
}
}
WebGLExtensionSRGB::~WebGLExtensionSRGB()
{
}
bool
WebGLExtensionSRGB::IsSupported(const WebGLContext* context)
{
gl::GLContext* gl = context->GL();
return gl->IsSupported(gl::GLFeature::sRGB);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionSRGB)

View File

@ -109,6 +109,18 @@ public:
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionSRGB
: public WebGLExtensionBase
{
public:
WebGLExtensionSRGB(WebGLContext*);
virtual ~WebGLExtensionSRGB();
static bool IsSupported(const WebGLContext* context);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionStandardDerivatives
: public WebGLExtensionBase
{

View File

@ -48,7 +48,7 @@ bool
WebGLFramebuffer::Attachment::HasAlpha() const {
GLenum format = 0;
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).Format();
format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat();
else if (Renderbuffer())
format = Renderbuffer()->InternalFormat();
return FormatHasAlpha(format);
@ -105,6 +105,26 @@ WebGLFramebuffer::Attachment::HasSameDimensionsAs(const Attachment& other) const
thisRect->HasSameDimensionsAs(*otherRect);
}
static inline bool
IsValidAttachedTextureColorFormat(GLenum format) {
return (
/* linear 8-bit formats */
format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_LUMINANCE ||
format == LOCAL_GL_LUMINANCE_ALPHA ||
format == LOCAL_GL_RGB ||
format == LOCAL_GL_RGBA ||
/* sRGB 8-bit formats */
format == LOCAL_GL_SRGB_EXT ||
format == LOCAL_GL_SRGB_ALPHA_EXT ||
/* linear float32 formats */
format == LOCAL_GL_ALPHA32F_ARB ||
format == LOCAL_GL_LUMINANCE32F_ARB ||
format == LOCAL_GL_LUMINANCE_ALPHA32F_ARB ||
format == LOCAL_GL_RGB32F_ARB ||
format == LOCAL_GL_RGBA32F_ARB);
}
bool
WebGLFramebuffer::Attachment::IsComplete() const {
const WebGLRectangleObject *thisRect = RectangleObject();
@ -118,7 +138,7 @@ WebGLFramebuffer::Attachment::IsComplete() const {
if (!mTexturePtr->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
return false;
GLenum format = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).Format();
GLenum format = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat();
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) {
return format == LOCAL_GL_DEPTH_COMPONENT;
@ -128,11 +148,7 @@ WebGLFramebuffer::Attachment::IsComplete() const {
}
else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
return (format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_LUMINANCE ||
format == LOCAL_GL_LUMINANCE_ALPHA ||
format == LOCAL_GL_RGB ||
format == LOCAL_GL_RGBA);
return IsValidAttachedTextureColorFormat(format);
}
MOZ_CRASH("Invalid WebGL attachment poin?");
}
@ -153,7 +169,8 @@ WebGLFramebuffer::Attachment::IsComplete() const {
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
return (format == LOCAL_GL_RGB565 ||
format == LOCAL_GL_RGB5_A1 ||
format == LOCAL_GL_RGBA4);
format == LOCAL_GL_RGBA4 ||
format == LOCAL_GL_SRGB8_ALPHA8_EXT);
}
MOZ_CRASH("Invalid WebGL attachment poin?");
}

View File

@ -107,6 +107,7 @@ WebGLRenderbuffer::MemoryUsage() const {
primarySize = 3*pixels;
break;
case LOCAL_GL_RGBA8:
case LOCAL_GL_SRGB8_ALPHA8_EXT:
case LOCAL_GL_DEPTH24_STENCIL8:
case LOCAL_GL_DEPTH_COMPONENT32:
primarySize = 4*pixels;

View File

@ -48,7 +48,7 @@ int64_t
WebGLTexture::ImageInfo::MemoryUsage() const {
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
return 0;
int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mFormat, mType);
int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mInternalFormat, mType);
return int64_t(mWidth) * int64_t(mHeight) * texelSizeInBits / 8;
}
@ -418,7 +418,7 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
mContext->MakeContextCurrent();
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget);
WebGLTexelFormat texelformat = GetWebGLTexelFormat(imageInfo.mFormat, imageInfo.mType);
WebGLTexelFormat texelformat = GetWebGLTexelFormat(imageInfo.mInternalFormat, imageInfo.mType);
uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
CheckedUint32 checked_byteLength
= WebGLContext::GetImageSize(
@ -430,9 +430,9 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
void *zeros = calloc(1, checked_byteLength.value());
mContext->UpdateWebGLErrorAndClearGLError();
mContext->gl->fTexImage2D(imageTarget, level, imageInfo.mFormat,
mContext->gl->fTexImage2D(imageTarget, level, imageInfo.mInternalFormat,
imageInfo.mWidth, imageInfo.mHeight,
0, imageInfo.mFormat, imageInfo.mType,
0, imageInfo.mInternalFormat, imageInfo.mType,
zeros);
GLenum error = LOCAL_GL_NO_ERROR;
mContext->UpdateWebGLErrorAndClearGLError(&error);

View File

@ -80,7 +80,7 @@ public:
{
public:
ImageInfo()
: mFormat(0)
: mInternalFormat(0)
, mType(0)
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
{}
@ -88,7 +88,7 @@ public:
ImageInfo(GLsizei width, GLsizei height,
GLenum format, GLenum type, WebGLImageDataStatus status)
: WebGLRectangleObject(width, height)
, mFormat(format)
, mInternalFormat(format)
, mType(type)
, mImageDataStatus(status)
{
@ -100,7 +100,7 @@ public:
return mImageDataStatus == a.mImageDataStatus &&
mWidth == a.mWidth &&
mHeight == a.mHeight &&
mFormat == a.mFormat &&
mInternalFormat == a.mInternalFormat &&
mType == a.mType;
}
bool operator!=(const ImageInfo& a) const {
@ -120,10 +120,10 @@ public:
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
}
int64_t MemoryUsage() const;
GLenum Format() const { return mFormat; }
GLenum InternalFormat() const { return mInternalFormat; }
GLenum Type() const { return mType; }
protected:
GLenum mFormat, mType;
GLenum mInternalFormat, mType;
WebGLImageDataStatus mImageDataStatus;
friend class WebGLTexture;

View File

@ -55,6 +55,7 @@ if CONFIG['MOZ_WEBGL']:
'WebGLExtensionElementIndexUint.cpp',
'WebGLExtensionInstancedArrays.cpp',
'WebGLExtensionLoseContext.cpp',
'WebGLExtensionSRGB.cpp',
'WebGLExtensionStandardDerivatives.cpp',
'WebGLExtensionTextureFilterAnisotropic.cpp',
'WebGLExtensionTextureFloat.cpp',

View File

@ -91,6 +91,7 @@ support-files =
[test_bug866575.html]
[test_bug902651.html]
[test_canvas.html]
[test_canvas_focusring.html]
[test_canvas_font_setter.html]
[test_canvas_strokeStyle_getter.html]
[test_drawImageIncomplete.html]

View File

@ -0,0 +1,18 @@
<!--docytpe html-->
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<script>
window.onload=function(){
var c=document.getElementById("myCanvas").getContext("2d");
c.beginPath();
c.strokeRect(10, 10, 200, 200);
}
</script>
</head>
<body>
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
</canvas>
</body></html>

View File

@ -0,0 +1,32 @@
<!--docytpe html-->
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<script>
window.onload=function(){
var c=document.getElementById("myCanvas").getContext("2d");
var in1=document.getElementById("in1");
var in2=document.getElementById("in2");
in1.onfocus=function(){
c.beginPath();
c.rect(10, 10, 200, 200);
if(c.drawCustomFocusRing(in1)) {
c.stroke();
}
c.beginPath();
c.rect(10, 220, 200, 200);
if(c.drawCustomFocusRing(in2)) {
c.stroke();
}
}
in1.focus();
}
</script>
</head>
<body>
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
<input id="in1" type="range" min="1" max="12">
<input id="in2" type="range" min="1" max="12">
</canvas>
</body></html>

View File

@ -0,0 +1,18 @@
<!--docytpe html-->
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<script>
window.onload=function(){
var c=document.getElementById("myCanvas").getContext("2d");
c.beginPath();
c.mozDash = [1,1];
c.strokeRect(10, 10, 200, 200);
}
</script>
</head>
<body>
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
</canvas>
</body></html>

View File

@ -0,0 +1,28 @@
<!--docytpe html-->
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<script>
window.onload=function(){
var c=document.getElementById("myCanvas").getContext("2d");
var in1=document.getElementById("in1");
var in2=document.getElementById("in2");
in1.onfocus=function(){
c.beginPath();
c.rect(10, 10, 200, 200);
c.drawSystemFocusRing(in1);
c.beginPath();
c.rect(10, 220, 200, 200);
c.drawSystemFocusRing(in2);
}
in1.focus();
}
</script>
</head>
<body>
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
<input id="in1" type="range" min="1" max="12">
<input id="in2" type="range" min="1" max="12">
</canvas>
</body></html>

View File

@ -188,3 +188,7 @@ skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,tr
# Bug 815648
== stroketext-shadow.html stroketext-shadow-ref.html
# focus rings
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawSystemFocusRing.html drawSystemFocusRing-ref.html
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html

View File

@ -0,0 +1,98 @@
<!DOCTYPE HTML>
<title>Canvas Tests</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<script>
SimpleTest.waitForExplicitFinish();
const Cc = SpecialPowers.Cc;
const Cr = SpecialPowers.Cr;
SpecialPowers.setBoolPref("canvas.focusring.enabled", true);
</script>
<p>Canvas test: drawCustomFocusRing</p>
<canvas id="c688" class="output" width="100" height="50">+
<input id="button1" type="range" min="1" max="12"></input>
<input id="button2" type="range" min="1" max="12"></input>
</canvas>
<script type="text/javascript">
function test_drawCustomFocusRing_canvas() {
var c = document.getElementById("c688");
var ctx = c.getContext("2d");
ctx.beginPath();
var b1 = document.getElementById('button1');
var b2 = document.getElementById('button2');
ok(!ctx.drawCustomFocusRing(b1), "button 1 is focused");
ok(!ctx.drawCustomFocusRing(b2), "button 2 is focused");
b1.focus();
ok(ctx.drawCustomFocusRing(b1), "button 1 should not be focused");
}
</script>
<p>Canvas test: drawSystemFocusRing</p>
<canvas id="c689" class="output" width="50" height="25">
<input id="button3" type="range" min="1" max="12"></input>
<input id="button4" type="range" min="1" max="12"></input>
</canvas>
<script type="text/javascript">
function isEmptyCanvas(ctx, w, h) {
var imgdata = ctx.getImageData(0, 0, w, h);
for(var x = 0; x < w*h*4; x++)
if(imgdata.data[x] != 0)
return false;
return true;
}
function test_drawSystemFocusRing_canvas() {
var c = document.getElementById("c689");
var ctx = c.getContext("2d");
var b1 = document.getElementById('button3');
var b2 = document.getElementById('button4');
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.rect(10, 10, 30, 30);
ctx.drawSystemFocusRing(b1);
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 1 is drawn");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.rect(50, 10, 30, 30);
ctx.drawSystemFocusRing(b2);
ctx.rect(50, 10, 30, 30);
ctx.drawSystemFocusRing(b2);
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 2 is drawn");
b1.focus();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.rect(10, 10, 30, 30);
ctx.drawSystemFocusRing(b1);
ok(!isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height) , "focus of button 1 is not drawn");
}
</script>
<script>
function runTests() {
try {
test_drawCustomFocusRing_canvas();
} catch(e) {
throw e;
ok(false, "unexpected exception thrown in: test_drawCustomFocusRing_canvas");
}
try {
test_drawSystemFocusRing_canvas();
} catch(e) {
throw e;
ok(false, "unexpected exception thrown in: test_drawSystemFocusRing_canvas");
}
SpecialPowers.setBoolPref("canvas.focusring.enabled", false);
SimpleTest.finish();
}
addLoadEvent(runTests);
</script>

View File

@ -6,4 +6,4 @@ webgl-debug-renderer-info.html
webgl-debug-shaders.html
--min-version 1.0.2 webgl-compressed-texture-s3tc.html
--min-version 1.0.2 webgl-depth-texture.html
ext-sRGB.html

View File

@ -0,0 +1,363 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test.js"></script>
<script src="../resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
<!-- Shaders to test output -->
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 aPosition;
void main() {
gl_Position = aPosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform float uColor;
void main() {
gl_FragColor = vec4(uColor, uColor, uColor, 1);
}
</script>
<script>
"use strict";
var wtu = WebGLTestUtils;
var canvas;
var gl;
var ext = null;
function getExtension() {
ext = gl.getExtension("EXT_sRGB");
}
function listsExtension() {
var supported = gl.getSupportedExtensions();
return (supported.indexOf("EXT_sRGB") >= 0);
}
function readLocation(x, y) {
var pixel = new Uint8Array(1 * 1 * 4);
var px = Math.floor(x * canvas.drawingBufferWidth);
var py = Math.floor(y * canvas.drawingBufferHeight);
gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
return pixel;
}
function toVec3String(val) {
if (typeof(val) == 'number') {
return toVec3String([val, val, val]);
}
return '[' + val[0] + ', ' + val[1] + ', ' + val[2] + ']';
}
var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
function expectResult(target, successMessage, failureMessage) {
var anyDiffer = false;
var source = readLocation(0.5, 0.5);
for (var m = 0; m < 3; m++) {
if (Math.abs(source[m] - target) > e) {
anyDiffer = true;
testFailed(failureMessage + "; should be " + toVec3String(target) + ", was " + toVec3String(source));
break;
}
}
if (!anyDiffer) {
testPassed(successMessage);
}
}
function createGreysRGBTexture(gl, color) {
var numPixels = gl.drawingBufferWidth * gl.drawingBufferHeight;
var size = numPixels * 3;
var buf = new Uint8Array(size);
for (var ii = 0; ii < numPixels; ++ii) {
var off = ii * 3;
buf[off + 0] = color;
buf[off + 1] = color;
buf[off + 2] = color;
}
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D,
0,
ext.SRGB_EXT,
gl.drawingBufferWidth,
gl.drawingBufferHeight,
0,
ext.SRGB_EXT,
gl.UNSIGNED_BYTE,
buf);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
return tex;
}
function testValidFormat(fn, internalFormat, formatName) {
fn(internalFormat);
glErrorShouldBe(gl, gl.NO_ERROR, "was able to create type " + formatName);
}
function testInvalidFormat(fn, internalFormat, formatName) {
fn(internalFormat);
var err = gl.getError();
if (err == gl.NO_ERROR) {
testFailed("should NOT be able to create type " + formatName);
} else if (err == gl.INVALID_OPERATION) {
testFailed("should return gl.INVALID_ENUM for type " + formatName);
} else if (err == gl.INVALID_ENUM) {
testPassed("not able to create invalid format: " + formatName);
}
}
var textureFormatFixture = {
desc: "Checking texture formats",
create: function(format) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D,
0, // level
format, // internalFormat
gl.drawingBufferWidth, // width
gl.drawingBufferHeight, // height
0, // border
format, // format
gl.UNSIGNED_BYTE, // type
null); // data
},
tests: [
{
desc: "Checking valid formats",
fn: testValidFormat,
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
},
{
desc: "Checking invalid formats",
fn: testInvalidFormat,
formats: [ 'SRGB8_ALPHA8_EXT' ]
}
]
};
var renderbufferFormatFixture = {
desc: "Checking renderbuffer formats",
create: function(format) {
var rbo = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
gl.renderbufferStorage(gl.RENDERBUFFER,
format,
gl.drawingBufferWidth,
gl.drawingBufferHeight);
},
tests: [
{
desc: "Checking valid formats",
fn: testValidFormat,
formats: [ 'SRGB8_ALPHA8_EXT' ]
},
{
desc: "Checking invalid formats",
fn: testInvalidFormat,
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
}
]
};
description("Test sRGB texture support");
debug("");
debug("Canvas.getContext");
canvas = document.getElementById("canvas");
gl = wtu.create3DContext(canvas);
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
debug("");
debug("Checking sRGB texture support");
// Query the extension and store globally so shouldBe can access it
ext = gl.getExtension("EXT_sRGB");
if (!ext) {
testPassed("No EXT_sRGB support -- this is legal");
runSupportedTest(false);
} else {
testPassed("Successfully enabled EXT_sRGB extension");
runSupportedTest(true);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
runFormatTest(textureFormatFixture);
runFormatTest(renderbufferFormatFixture);
runTextureReadConversionTest();
runFramebufferTextureConversionTest();
runFramebufferRenderbufferConversionTest();
}
}
function runSupportedTest(extensionEnabled) {
if (listsExtension()) {
if (extensionEnabled) {
testPassed("EXT_sRGB listed as supported and getExtension succeeded");
} else {
testFailed("EXT_sRGB listed as supported but getExtension failed");
}
} else {
if (extensionEnabled) {
testFailed("EXT_sRGB not listed as supported but getExtension succeeded");
} else {
testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal");
}
}
}
function runFormatTest(fixture) {
debug("");
debug(fixture.desc);
for (var tt = 0; tt < fixture.tests.length; ++tt) {
var test = fixture.tests[tt];
debug(test.desc);
for (var ii = 0; ii < test.formats.length; ++ii) {
var formatName = test.formats[ii];
test.fn(fixture.create, ext[formatName], "ext." + formatName);
}
if (tt != fixture.tests.length - 1)
debug("");
}
}
function runTextureReadConversionTest() {
debug("");
debug("Test the conversion of colors from sRGB to linear on texture read");
// Draw
var conversions = [
[ 0, 0 ],
[ 63, 13 ],
[ 127, 54 ],
[ 191, 133 ],
[ 255, 255 ]
];
var program = wtu.setupTexturedQuad(gl);
gl.uniform1i(gl.getUniformLocation(program, "tex2d"), 0);
for (var ii = 0; ii < conversions.length; ii++) {
var tex = createGreysRGBTexture(gl, conversions[ii][0]);
wtu.drawQuad(gl);
expectResult(conversions[ii][1],
"sRGB texture read returned correct data",
"sRGB texture read returned incorrect data");
}
}
function runFramebufferTextureConversionTest() {
debug("");
debug("Test the conversion of colors from linear to sRGB on framebuffer (texture) write");
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
var tex = createGreysRGBTexture(gl, 0);
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
glErrorShouldBe(gl, gl.NO_ERROR);
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
// Draw
var conversions = [
[ 0, 0 ],
[ 13, 63 ],
[ 54, 127 ],
[ 133, 191 ],
[ 255, 255 ]
];
wtu.setupUnitQuad(gl, 0);
for (var ii = 0; ii < conversions.length; ii++) {
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
wtu.drawQuad(gl, [0, 0, 0, 0]);
expectResult(conversions[ii][1],
"framebuffer (texture) read returned correct data",
"framebuffer (texture) read returned incorrect data");
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
function runFramebufferRenderbufferConversionTest() {
debug("");
debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write");
function createsRGBFramebuffer(gl, width, height) {
var rbo = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
gl.renderbufferStorage(gl.RENDERBUFFER, ext.SRGB8_ALPHA8_EXT, width, height);
glErrorShouldBe(gl, gl.NO_ERROR);
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.RENDERBUFFER, rbo);
glErrorShouldBe(gl, gl.NO_ERROR);
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
return fbo;
}
// Draw
var conversions = [
[ 0, 0 ],
[ 13, 63 ],
[ 54, 127 ],
[ 133, 191 ],
[ 255, 255 ]
];
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
wtu.setupUnitQuad(gl, 0);
var fbo = createsRGBFramebuffer(gl, 4, 4);
for (var ii = 0; ii < conversions.length; ii++) {
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
wtu.drawQuad(gl, [0, 0, 0, 0]);
expectResult(conversions[ii][1],
"framebuffer (renderbuffer) read returned the correct data",
"framebuffer (renderbuffer) read returned incorrect data");
}
}
debug("");
var successfullyParsed = true;
</script>
<script>finishTest();</script>
</body>
</html>

View File

@ -142,7 +142,8 @@ public:
// mLeftOverData != INT_MIN means that the panning model was HRTF and a
// tail-time reference was added. Even if the model is now equalpower,
// the reference will need to be removed.
if (mLeftOverData > 0) {
if (mLeftOverData > 0 &&
mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
} else {
if (mLeftOverData != INT_MIN) {

View File

@ -3762,7 +3762,7 @@ nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::Value* aVal)
ErrorResult rv;
JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv));
if (!rv.Failed()) {
*aVal = JS::ObjectValue(*content);
*aVal = JS::ObjectOrNullValue(content);
}
return rv.ErrorCode();

View File

@ -1310,6 +1310,11 @@ DOMInterfaces = {
'headerFile': 'WebGLExtensions.h'
},
'WebGLExtensionSRGB': {
'nativeType': 'mozilla::WebGLExtensionSRGB',
'headerFile': 'WebGLExtensions.h'
},
'WebGLExtensionStandardDerivatives': {
'nativeType': 'mozilla::WebGLExtensionStandardDerivatives',
'headerFile': 'WebGLExtensions.h'

View File

@ -80,6 +80,7 @@ class nsGeolocationRequest
void SendLocation(nsIDOMGeoPosition* location);
bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
void SetTimeoutTimer();
void NotifyErrorAndShutdown(uint16_t);
nsIPrincipal* GetPrincipal();
~nsGeolocationRequest();
@ -350,6 +351,13 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
NS_IMETHODIMP
nsGeolocationRequest::Notify(nsITimer* aTimer)
{
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
return NS_OK;
}
void
nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
{
MOZ_ASSERT(!mShutdown, "timeout after shutdown");
@ -358,13 +366,11 @@ nsGeolocationRequest::Notify(nsITimer* aTimer)
mLocator->RemoveRequest(this);
}
NotifyError(nsIDOMGeoPositionError::TIMEOUT);
NotifyError(aErrorCode);
if (!mShutdown) {
SetTimeoutTimer();
}
return NS_OK;
}
NS_IMETHODIMP
@ -1140,13 +1146,13 @@ Geolocation::NotifyError(uint16_t aErrorCode)
}
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
mPendingCallbacks[i-1]->NotifyError(aErrorCode);
RemoveRequest(mPendingCallbacks[i-1]);
mPendingCallbacks[i-1]->NotifyErrorAndShutdown(aErrorCode);
//NotifyErrorAndShutdown() removes the request from the array
}
// notify everyone that is watching
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
mWatchingCallbacks[i]->NotifyError(aErrorCode);
mWatchingCallbacks[i]->NotifyErrorAndShutdown(aErrorCode);
}
return NS_OK;

View File

@ -175,22 +175,30 @@ WifiGeoPositionProvider.prototype = {
// This is a background load
xhr.open("POST", url, true);
try {
xhr.open("POST", url, true);
} catch (e) {
triggerError();
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.responseType = "json";
xhr.mozBackgroundRequest = true;
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
xhr.onerror = function() {
LOG("onerror: " + xhr);
triggerError();
};
xhr.onload = function() {
LOG("gls returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if (xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) {
triggerError();
return;
}
if (!xhr.response || !xhr.response.location) {
triggerError();
return;
}
@ -223,4 +231,8 @@ WifiGeoPositionProvider.prototype = {
},
};
function triggerError() {
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
.notifyError(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE);
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);

View File

@ -51,6 +51,11 @@ function delay_geolocationProvider(delay, callback)
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
}
function send404_geolocationProvider(callback)
{
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=send404"]]}, callback);
}
function check_geolocation(location) {
ok(location, "Check to see if this location is non-null");

View File

@ -12,6 +12,7 @@ support-files =
[test_cancelWatch.html]
[test_clearWatch.html]
[test_clearWatch_invalid.html]
[test_errorcheck.html]
[test_geolocation_is_undefined_when_pref_is_off.html]
[test_handlerSpinsEventLoop.html]
[test_manyCurrentConcurrent.html]

View File

@ -37,6 +37,7 @@ function handleRequest(request, response)
var params = parseQueryString(request.queryString);
if (params.action == "stop-responding") {
response.processAsync();
return;
}
@ -64,6 +65,10 @@ function handleRequest(request, response)
if ('delay' in params) {
delay = params.delay;
}
if (params.action === "send404") {
response.setStatusLine("1.0", 404, "Not Found");
position = '';
}
timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(function() {
response.write(position);

View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=684722
-->
<head>
<title>Test for ErrorChecking </title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="geolocation_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684722">Mozilla Bug 684722</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function test1() {
send404_geolocationProvider(test2);
}
function errorCallback(error) {
is(error.code,
SpecialPowers.Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE, "Geolocation error handler fired");
SimpleTest.finish();
}
function successCallback(position) {
test2();
}
function test2() {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
</script>
</pre>
</body>
</html>

View File

@ -77,10 +77,10 @@ interface CanvasRenderingContext2D {
// NOT IMPLEMENTED void fill(Path path);
void stroke();
// NOT IMPLEMENTED void stroke(Path path);
// NOT IMPLEMENTED void drawSystemFocusRing(Element element);
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, Element element);
// NOT IMPLEMENTED boolean drawCustomFocusRing(Element element);
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
[Pref="canvas.focusring.enabled"] void drawSystemFocusRing(Element element);
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, HTMLElement element);
[Pref="canvas.focusring.enabled"] boolean drawCustomFocusRing(Element element);
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, HTMLElement element);
// NOT IMPLEMENTED void scrollPathIntoView();
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
void clip(optional CanvasWindingRule winding = "nonzero");

View File

@ -830,6 +830,15 @@ interface WebGLExtensionTextureFilterAnisotropic
const GLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
};
[NoInterfaceObject]
interface WebGLExtensionSRGB
{
const GLenum SRGB_EXT = 0x8C40;
const GLenum SRGB_ALPHA_EXT = 0x8C42;
const GLenum SRGB8_ALPHA8_EXT = 0x8C43;
const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210;
};
[NoInterfaceObject]
interface WebGLExtensionStandardDerivatives {
const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;

View File

@ -74,23 +74,19 @@ struct NativeFont {
* mCompositionOp - The operator that indicates how the source and destination
* patterns are blended.
* mAntiAliasMode - The AntiAlias mode used for this drawing operation.
* mSnapping - Whether this operation is snapped to pixel boundaries.
*/
struct DrawOptions {
DrawOptions(Float aAlpha = 1.0f,
CompositionOp aCompositionOp = OP_OVER,
AntialiasMode aAntialiasMode = AA_DEFAULT,
Snapping aSnapping = SNAP_NONE)
AntialiasMode aAntialiasMode = AA_DEFAULT)
: mAlpha(aAlpha)
, mCompositionOp(aCompositionOp)
, mAntialiasMode(aAntialiasMode)
, mSnapping(aSnapping)
{}
Float mAlpha;
CompositionOp mCompositionOp : 8;
AntialiasMode mAntialiasMode : 3;
Snapping mSnapping : 1;
};
/*

View File

@ -296,8 +296,6 @@ struct AutoPaintSetup {
mPaint.setAntiAlias(false);
}
MOZ_ASSERT(aOptions.mSnapping == SNAP_NONE, "Pixel snapping not supported yet!");
// TODO: We could skip the temporary for operator_source and just
// clear the clip rect. The other operators would be harder
// but could be worth it to skip pushing a group.

View File

@ -104,7 +104,6 @@ enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST
enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
enum Snapping { SNAP_NONE, SNAP_ALIGNED };
enum Filter { FILTER_GOOD, FILTER_LINEAR, FILTER_POINT };
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };

View File

@ -116,6 +116,10 @@ static const char *sExtensionNames[] = {
"GL_EXT_transform_feedback",
"GL_NV_transform_feedback",
"GL_ANGLE_depth_texture",
"GL_EXT_sRGB",
"GL_EXT_texture_sRGB",
"GL_ARB_framebuffer_sRGB",
"GL_EXT_framebuffer_sRGB",
"GL_KHR_debug",
nullptr
};
@ -599,7 +603,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (Renderer() == RendererAdrenoTM320) {
MarkUnsupported(GLFeature::standard_derivatives);
}
#ifdef XP_MACOSX
// The Mac Nvidia driver, for versions up to and including 10.8, don't seem
// to properly support this. See 814839
@ -1204,6 +1208,29 @@ GLContext::CanUploadSubTextures()
return true;
}
bool
GLContext::CanReadSRGBFromFBOTexture()
{
if (!mWorkAroundDriverBugs)
return true;
#ifdef XP_MACOSX
// Bug 843668:
// MacOSX 10.6 reports to support EXT_framebuffer_sRGB and
// EXT_texture_sRGB but fails to convert from sRGB to linear
// when writing to an sRGB texture attached to an FBO.
SInt32 major, minor;
::Gestalt(gestaltSystemVersionMajor, &major);
::Gestalt(gestaltSystemVersionMinor, &minor);
if (major == 10 && minor <= 6) {
return false;
}
#endif // XP_MACOSX
return true;
}
bool GLContext::sPowerOfTwoForced = false;
bool GLContext::sPowerOfTwoPrefCached = false;

View File

@ -99,6 +99,7 @@ namespace GLFeature {
packed_depth_stencil,
query_objects,
robustness,
sRGB,
standard_derivatives,
texture_float,
texture_float_linear,
@ -395,6 +396,10 @@ public:
EXT_transform_feedback,
NV_transform_feedback,
ANGLE_depth_texture,
EXT_sRGB,
EXT_texture_sRGB,
ARB_framebuffer_sRGB,
EXT_framebuffer_sRGB,
KHR_debug,
Extensions_Max,
Extensions_End
@ -2448,6 +2453,7 @@ public:
}
bool CanUploadSubTextures();
bool CanReadSRGBFromFBOTexture();
static void PlatformStartup();

View File

@ -195,7 +195,7 @@ static const FeatureInfo sFeatureInfoArr[] = {
/*
* XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
* but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
* it is supported on desktop if ARB_ES3_compatibility because
* it is supported on desktop if ARB_ES3_compatibility because
* EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
*/
},
@ -249,6 +249,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End
}
},
{
"sRGB",
300, // OpenGL version
300, // OpenGL ES version
{
GLContext::EXT_sRGB,
GLContext::Extensions_End
}
},
{
"standard_derivatives",
200, // OpenGL version
@ -387,6 +396,18 @@ GLContext::InitFeatures()
}
}
}
// Bug 843668: Work around limitation of the feature system.
// For sRGB support under OpenGL to match OpenGL ES spec, check for both
// EXT_texture_sRGB and EXT_framebuffer_sRGB is required.
const bool aresRGBExtensionsAvailable =
IsExtensionSupported(EXT_texture_sRGB) &&
(IsExtensionSupported(ARB_framebuffer_sRGB) ||
IsExtensionSupported(EXT_framebuffer_sRGB));
mAvailableFeatures[GLFeature::sRGB] =
aresRGBExtensionsAvailable &&
CanReadSRGBFromFBOTexture();
}
void

View File

@ -501,6 +501,7 @@ CompositorParent::ScheduleComposition()
void
CompositorParent::Composite()
{
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START);
PROFILER_LABEL("CompositorParent", "Composite");
NS_ABORT_IF_FALSE(CompositorThreadID() == PlatformThread::CurrentId(),
"Composite can only be called on the compositor thread");

View File

@ -123,7 +123,7 @@ if os_win:
'src/chrome/common/process_watcher_win.cc',
'src/chrome/common/transport_dib_win.cc',
]
else:
elif not CONFIG['MOZ_NATIVE_LIBEVENT']:
SOURCES += [
'src/third_party/libevent/buffer.c',
'src/third_party/libevent/bufferevent.c',
@ -203,9 +203,10 @@ if os_macosx:
'src/chrome/common/chrome_paths_mac.mm',
'src/chrome/common/mach_ipc_mac.mm',
]
SOURCES += [
'src/third_party/libevent/kqueue.c',
]
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
SOURCES += [
'src/third_party/libevent/kqueue.c',
]
if os_linux:
SOURCES += [
@ -227,13 +228,14 @@ if os_linux:
GENERATED_SOURCES += [
'src/base/moc_message_pump_qt.cc',
]
if CONFIG['OS_TARGET'] != 'Android':
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
if CONFIG['OS_TARGET'] != 'Android':
SOURCES += [
'src/third_party/libevent/epoll_sub.c',
]
SOURCES += [
'src/third_party/libevent/epoll_sub.c',
'src/third_party/libevent/epoll.c',
]
SOURCES += [
'src/third_party/libevent/epoll.c',
]
if os_bsd:
SOURCES += [
@ -259,9 +261,10 @@ if os_bsd:
GENERATED_SOURCES += [
'src/base/moc_message_pump_qt.cc',
]
SOURCES += [
'src/third_party/libevent/kqueue.c',
]
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
SOURCES += [
'src/third_party/libevent/kqueue.c',
]
if CONFIG['_MSC_VER']:
SOURCES += [

View File

@ -8,6 +8,7 @@
#define js_RootingAPI_h
#include "mozilla/GuardObjects.h"
#include "mozilla/LinkedList.h"
#include "mozilla/NullPtr.h"
#include "mozilla/TypeTraits.h"
@ -143,6 +144,7 @@ struct Cell;
namespace JS {
template <typename T> class Rooted;
template <typename T> class PersistentRooted;
/* This is exposing internal state of the GC for inlining purposes. */
JS_FRIEND_API(bool) isGCEnabled();
@ -440,6 +442,11 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
Handle(const Rooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
template <typename S>
inline
Handle(const PersistentRooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
/* Construct a read only handle from a mutable handle. */
template <typename S>
inline
@ -484,6 +491,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
{
public:
inline MutableHandle(Rooted<T> *root);
inline MutableHandle(PersistentRooted<T> *root);
MutableHandle(int) MOZ_DELETE;
#ifdef MOZ_HAVE_CXX11_NULLPTR
MutableHandle(decltype(nullptr)) MOZ_DELETE;
@ -797,13 +805,6 @@ template <>
class Rooted<JSStableString *>;
#endif
typedef Rooted<JSObject*> RootedObject;
typedef Rooted<JSFunction*> RootedFunction;
typedef Rooted<JSScript*> RootedScript;
typedef Rooted<JSString*> RootedString;
typedef Rooted<jsid> RootedId;
typedef Rooted<JS::Value> RootedValue;
} /* namespace JS */
namespace js {
@ -1024,6 +1025,14 @@ Handle<T>::Handle(const Rooted<S> &root,
ptr = reinterpret_cast<const T *>(root.address());
}
template <typename T> template <typename S>
inline
Handle<T>::Handle(const PersistentRooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
{
ptr = reinterpret_cast<const T *>(root.address());
}
template <typename T> template <typename S>
inline
Handle<T>::Handle(MutableHandle<S> &root,
@ -1041,6 +1050,123 @@ MutableHandle<T>::MutableHandle(Rooted<T> *root)
ptr = root->address();
}
template <typename T>
inline
MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
{
static_assert(sizeof(MutableHandle<T>) == sizeof(T *),
"MutableHandle must be binary compatible with T*.");
ptr = root->address();
}
/*
* A copyable, assignable global GC root type with arbitrary lifetime, an
* infallible constructor, and automatic unrooting on destruction.
*
* These roots can be used in heap-allocated data structures, so they are not
* associated with any particular JSContext or stack. They are registered with
* the JSRuntime itself, without locking, so they require a full JSContext to be
* constructed, not one of its more restricted superclasses.
*
* Note that you must not use an PersistentRooted in an object owned by a JS
* object:
*
* Whenever one object whose lifetime is decided by the GC refers to another
* such object, that edge must be traced only if the owning JS object is traced.
* This applies not only to JS objects (which obviously are managed by the GC)
* but also to C++ objects owned by JS objects.
*
* If you put a PersistentRooted in such a C++ object, that is almost certainly
* a leak. When a GC begins, the referent of the PersistentRooted is treated as
* live, unconditionally (because a PersistentRooted is a *root*), even if the
* JS object that owns it is unreachable. If there is any path from that
* referent back to the JS object, then the C++ object containing the
* PersistentRooted will not be destructed, and the whole blob of objects will
* not be freed, even if there are no references to them from the outside.
*
* In the context of Firefox, this is a severe restriction: almost everything in
* Firefox is owned by some JS object or another, so using PersistentRooted in
* such objects would introduce leaks. For these kinds of edges, Heap<T> or
* TenuredHeap<T> would be better types. It's up to the implementor of the type
* containing Heap<T> or TenuredHeap<T> members to make sure their referents get
* marked when the object itself is marked.
*/
template<typename T>
class PersistentRooted : public mozilla::LinkedListElement<PersistentRooted<T> > {
typedef mozilla::LinkedList<PersistentRooted> List;
typedef mozilla::LinkedListElement<PersistentRooted> Element;
void registerWithRuntime(JSRuntime *rt) {
JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);
srt->getPersistentRootedList<T>().insertBack(this);
}
public:
PersistentRooted(JSContext *cx) : ptr(js::GCMethods<T>::initial())
{
registerWithRuntime(js::GetRuntime(cx));
}
PersistentRooted(JSContext *cx, T initial) : ptr(initial)
{
registerWithRuntime(js::GetRuntime(cx));
}
PersistentRooted(JSRuntime *rt) : ptr(js::GCMethods<T>::initial())
{
registerWithRuntime(rt);
}
PersistentRooted(JSRuntime *rt, T initial) : ptr(initial)
{
registerWithRuntime(rt);
}
PersistentRooted(PersistentRooted &rhs) : ptr(rhs.ptr)
{
/*
* Copy construction takes advantage of the fact that the original
* is already inserted, and simply adds itself to whatever list the
* original was on - no JSRuntime pointer needed.
*/
rhs.setNext(this);
}
/*
* Important: Return a reference here so passing a Rooted<T> to
* something that takes a |const T&| is not a GC hazard.
*/
operator const T&() const { return ptr; }
T operator->() const { return ptr; }
T *address() { return &ptr; }
const T *address() const { return &ptr; }
T &get() { return ptr; }
const T &get() const { return ptr; }
T &operator=(T value) {
JS_ASSERT(!js::GCMethods<T>::poisoned(value));
ptr = value;
return ptr;
}
T &operator=(const PersistentRooted &value) {
ptr = value;
return ptr;
}
void set(T value) {
JS_ASSERT(!js::GCMethods<T>::poisoned(value));
ptr = value;
}
bool operator!=(const T &other) const { return ptr != other; }
bool operator==(const T &other) const { return ptr == other; }
private:
T ptr;
};
} /* namespace JS */
namespace js {

View File

@ -57,6 +57,8 @@ namespace JS {
class Value;
template <typename T> class Handle;
template <typename T> class MutableHandle;
template <typename T> class Rooted;
template <typename T> class PersistentRooted;
typedef Handle<JSFunction*> HandleFunction;
typedef Handle<jsid> HandleId;
@ -72,6 +74,20 @@ typedef MutableHandle<JSScript*> MutableHandleScript;
typedef MutableHandle<JSString*> MutableHandleString;
typedef MutableHandle<Value> MutableHandleValue;
typedef Rooted<JSObject*> RootedObject;
typedef Rooted<JSFunction*> RootedFunction;
typedef Rooted<JSScript*> RootedScript;
typedef Rooted<JSString*> RootedString;
typedef Rooted<jsid> RootedId;
typedef Rooted<JS::Value> RootedValue;
typedef PersistentRooted<JSFunction*> PersistentRootedFunction;
typedef PersistentRooted<jsid> PersistentRootedId;
typedef PersistentRooted<JSObject*> PersistentRootedObject;
typedef PersistentRooted<JSScript*> PersistentRootedScript;
typedef PersistentRooted<JSString*> PersistentRootedString;
typedef PersistentRooted<Value> PersistentRootedValue;
} // namespace JS
#endif /* js_TypeDecls_h */

View File

@ -94,6 +94,14 @@ using JS::RootedScript;
using JS::RootedString;
using JS::RootedValue;
using JS::PersistentRooted;
using JS::PersistentRootedFunction;
using JS::PersistentRootedId;
using JS::PersistentRootedObject;
using JS::PersistentRootedScript;
using JS::PersistentRootedString;
using JS::PersistentRootedValue;
using JS::Handle;
using JS::HandleFunction;
using JS::HandleId;

View File

@ -95,6 +95,7 @@ oddly_ordered_inclnames = set([
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
'jsautokw.h', # Included in the body of frontend/TokenStream.h
'jswin.h', # Must be #included before <psapi.h>
'machine/endian.h', # Must be included after <sys/types.h> on BSD
'winbase.h', # Must precede other system headers(?)
'windef.h' # Must precede other system headers(?)
])

View File

@ -195,9 +195,8 @@ MOZ_PSEUDO_DERECURSE :=
endif
endif
# Disable MOZ_PSEUDO_DERECURSE on the second PGO pass until it's widely
# tested.
ifdef MOZ_PROFILE_USE
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
MOZ_PSEUDO_DERECURSE :=
endif

View File

@ -1331,7 +1331,7 @@ endif
endif
endif
libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
libs realchrome:: $(FINAL_TARGET)/chrome
$(call py_action,jar_maker,\
$(QUIET) -j $(FINAL_TARGET)/chrome \
$(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \

View File

@ -49,6 +49,9 @@ ffi_call_SYSV:
movl 16(%ebp),%ecx
subl %ecx,%esp
/* Align the stack pointer to 16-bytes */
andl $0xfffffff0, %esp
movl %esp,%eax
/* Place all of the ffi_prep_args in position */

View File

@ -0,0 +1,31 @@
# HG changeset patch
# User Landry Breuil <landry@openbsd.org>
# Date 1382105758 -7200
# Fri Oct 18 16:15:58 2013 +0200
# Node ID 5f82dae8c495a7fddf5ed935eb2a8be7f47b9bd8
# Parent d50df2233e95f4d45b35eddbfbe84bcdda6a11e2
Bug 928381 - ctypes/libffi: Fix stack alignment on *BSD/i386 r=glandium
diff --git a/js/src/ctypes/libffi/src/x86/freebsd.S b/js/src/ctypes/libffi/src/x86/freebsd.S
--- a/js/src/ctypes/libffi/src/x86/freebsd.S
+++ b/js/src/ctypes/libffi/src/x86/freebsd.S
@@ -44,16 +44,19 @@ ffi_call_SYSV:
pushl %ebp
.LCFI0:
movl %esp,%ebp
.LCFI1:
/* Make room for all of the new args. */
movl 16(%ebp),%ecx
subl %ecx,%esp
+ /* Align the stack pointer to 16-bytes */
+ andl $0xfffffff0, %esp
+
movl %esp,%eax
/* Place all of the ffi_prep_args in position */
pushl 12(%ebp)
pushl %eax
call *8(%ebp)
/* Return stack to previous state and call the function */

View File

@ -126,7 +126,7 @@ FoldBinaryNumeric(ExclusiveContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
i = ToInt32(d);
j = ToInt32(d2);
j &= 31;
d = (op == JSOP_LSH) ? i << j : i >> j;
d = int32_t((op == JSOP_LSH) ? uint32_t(i) << j : i >> j);
break;
case JSOP_URSH:

View File

@ -14,6 +14,9 @@
namespace js {
namespace gc {
void
MarkPersistentRootedChains(JSTracer *trc);
void
MarkRuntime(JSTracer *trc, bool useSavedRoots = false);

View File

@ -617,6 +617,44 @@ JSPropertyDescriptor::trace(JSTracer *trc)
}
}
// Mark a chain of PersistentRooted pointers that might be null.
template<typename Referent>
static void
MarkPersistentRootedChain(JSTracer *trc,
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
const char *name)
{
for (PersistentRooted<Referent *> *r = list.getFirst();
r != nullptr;
r = r->getNext())
{
if (r->get())
marker(trc, r->address(), name);
}
}
void
js::gc::MarkPersistentRootedChains(JSTracer *trc)
{
JSRuntime *rt = trc->runtime;
MarkPersistentRootedChain(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSFunction *>");
MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSObject *>");
MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
"PersistentRooted<JSScript *>");
MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot,
"PersistentRooted<JSString *>");
// Mark the PersistentRooted chains of types that are never null.
for (JS::PersistentRootedId *r = rt->idPersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
MarkIdRoot(trc, r->address(), "PersistentRooted<jsid>");
for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
MarkValueRoot(trc, r->address(), "PersistentRooted<Value>");
}
void
js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
{
@ -661,6 +699,8 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
}
}
MarkPersistentRootedChains(trc);
if (rt->scriptAndCountsVector) {
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
for (size_t i = 0; i < vec.length(); i++)

View File

@ -11,3 +11,19 @@ assertIteratorNext(it, 1000);
assertIteratorNext(it, 1);
assertIteratorNext(it, 2000);
assertIteratorDone(it, undefined);
// test that .keys() and .entries() have the same behaviour
arr = [0, 1, 2];
var ki = arr.keys();
var ei = arr.entries();
arr[0] = 1000;
arr[2] = 2000;
assertIteratorNext(ki, 0);
assertIteratorNext(ei, [0, 1000]);
assertIteratorNext(ki, 1);
assertIteratorNext(ei, [1, 1]);
assertIteratorNext(ki, 2);
assertIteratorNext(ei, [2, 2000]);
assertIteratorDone(ki, undefined);
assertIteratorDone(ei, undefined);

View File

@ -0,0 +1,11 @@
// Array.keys() and .entries() on an empty array produce empty iterators
var arr = [];
var ki = arr.keys(), ei = arr.entries();
var p = Object.getPrototypeOf(ki);
assertEq(Object.getPrototypeOf(ei), p);
for (let k of ki)
throw "FAIL";
for (let [k, v] of ei)
throw "FAIL";

View File

@ -6,9 +6,16 @@ load(libdir + "iteration.js");
function test(obj) {
var it = Array.prototype[std_iterator].call(obj);
for (var i = 0; i < (obj.length >>> 0); i++)
var ki = Array.prototype.keys.call(obj);
var ei = Array.prototype.entries.call(obj);
for (var i = 0; i < (obj.length >>> 0); i++) {
assertIteratorNext(it, obj[i]);
assertIteratorNext(ki, i);
assertIteratorNext(ei, [i, obj[i]]);
}
assertIteratorDone(it, undefined);
assertIteratorDone(ki, undefined);
assertIteratorDone(ei, undefined);
}
test({length: 0});

View File

@ -5,10 +5,22 @@ load(libdir + "iteration.js");
var arr = [0, 1];
var it = arr[std_iterator]();
var ki = arr.keys();
var ei = arr.entries();
assertIteratorNext(it, 0);
assertIteratorNext(ki, 0);
assertIteratorNext(ei, [0, 0]);
assertIteratorNext(it, 1);
assertIteratorNext(ki, 1);
assertIteratorNext(ei, [1, 1]);
arr[2] = 2;
arr.length = 4;
assertIteratorNext(it, 2);
assertIteratorNext(ki, 2);
assertIteratorNext(ei, [2, 2]);
assertIteratorNext(it, undefined);
assertIteratorNext(ki, 3);
assertIteratorNext(ei, [3, undefined]);
assertIteratorDone(it, undefined);
assertIteratorDone(ki, undefined);
assertIteratorDone(ei, undefined);

View File

@ -0,0 +1,16 @@
// array.keys() returns an iterator over the index of elements
// and array.entries() returns an iterator that yields pairs [index, element].
load(libdir + "iteration.js");
var data = [1, 2, 3, "abc"];
var ki = data.keys();
for (var i = 0; i < data.length; i++)
assertIteratorResult(ki.next(), i, false);
assertIteratorDone(ki, undefined);
var ei = data.entries();
for (var i = 0; i < data.length; i++)
assertIteratorResult(ei.next(), [i, data[i]], false);
assertIteratorDone(ei, undefined);

View File

@ -6,4 +6,6 @@ load(libdir + "iteration.js");
for (var v of [undefined, null]) {
// ES6 draft 2013-09-05 section 22.1.5.1.
assertThrowsInstanceOf(function () { Array.prototype[std_iterator].call(v); }, TypeError);
assertThrowsInstanceOf(function () { Array.prototype.keys.call(v); }, TypeError);
assertThrowsInstanceOf(function () { Array.prototype.entries.call(v); }, TypeError);
}

View File

@ -4,7 +4,8 @@ load(libdir + "asserts.js");
load(libdir + "iteration.js");
var s = '';
var it = Array.prototype[std_iterator].call(Proxy.create({
var proxyObj = {
get: function (recipient, name) {
if (name == 'length') {
s += 'L';
@ -14,7 +15,9 @@ var it = Array.prototype[std_iterator].call(Proxy.create({
return name;
}
}
}));
};
var it = Array.prototype[std_iterator].call(Proxy.create(proxyObj));
assertIteratorNext(it, "0");
s += ' ';
@ -22,3 +25,23 @@ assertIteratorNext(it, "1");
s += ' ';
assertIteratorDone(it, undefined);
assertEq(s, "L0 L1 L");
s = '';
var ki = Array.prototype.keys.call(Proxy.create(proxyObj));
assertIteratorNext(ki, 0);
s += ' ';
assertIteratorNext(ki, 1);
s += ' ';
assertIteratorDone(ki, undefined);
assertEq(s, "L L L");
s = '';
var ei = Array.prototype.entries.call(Proxy.create(proxyObj));
assertIteratorNext(ei, [0, "0"]);
s += ' ';
assertIteratorNext(ei, [1, "1"]);
s += ' ';
assertIteratorDone(ei, undefined);
assertEq(s, "L0 L1 L");

View File

@ -5,7 +5,16 @@ load(libdir + "iteration.js");
var arr = [0, 1, 2];
var it = arr[std_iterator]();
var ki = arr.keys();
var ei = arr.entries();
assertIteratorNext(it, 0);
assertIteratorNext(it, 1);
assertIteratorNext(ki, 0);
assertIteratorNext(ki, 1);
assertIteratorNext(ei, [0, 0]);
assertIteratorNext(ei, [1, 1]);
arr.length = 1;
assertIteratorDone(it, undefined);
assertIteratorDone(ki, undefined);
assertIteratorDone(ei, undefined);

View File

@ -4,6 +4,10 @@ load(libdir + "iteration.js");
var proto = Object.getPrototypeOf([][std_iterator]());
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
proto = Object.getPrototypeOf([].keys());
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
proto = Object.getPrototypeOf([].entries());
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
function check(it) {
assertEq(typeof it, 'object');
@ -21,3 +25,7 @@ function check(it) {
check([][std_iterator]());
check(Array.prototype[std_iterator].call({}));
check([].keys());
check(Array.prototype.keys.call({}));
check([].entries());
check(Array.prototype.entries.call({}));

View File

@ -50,6 +50,7 @@ SOURCES += [
'testOps.cpp',
'testOriginPrincipals.cpp',
'testParseJSON.cpp',
'testPersistentRooted.cpp',
'testProfileStrings.cpp',
'testPropCache.cpp',
'testRegExp.cpp',

View File

@ -0,0 +1,185 @@
/* 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/. */
#if defined(JSGC_USE_EXACT_ROOTING)
#include "js/Class.h"
#include "jsapi-tests/tests.h"
using namespace JS;
struct BarkWhenTracedClass {
static int finalizeCount;
static int traceCount;
static const JSClass class_;
static void finalize(JSFreeOp *fop, JSObject *obj) { finalizeCount++; }
static void trace(JSTracer *trc, JSObject *obj) { traceCount++; }
static void reset() { finalizeCount = 0; traceCount = 0; }
};
int BarkWhenTracedClass::finalizeCount;
int BarkWhenTracedClass::traceCount;
const JSClass BarkWhenTracedClass::class_ = {
"BarkWhenTracedClass", 0,
JS_PropertyStub,
JS_DeletePropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
finalize,
nullptr,
nullptr,
nullptr,
nullptr,
trace
};
struct Kennel {
PersistentRootedObject obj;
Kennel(JSContext *cx) : obj(cx) { }
Kennel(JSContext *cx, const HandleObject &woof) : obj(cx, woof) { };
};
// A function for allocating a Kennel and a barker. Only allocating
// PersistentRooteds on the heap, and in this function, helps ensure that the
// conservative GC doesn't find stray references to the barker. Ugh.
JS_NEVER_INLINE static Kennel *
Allocate(JSContext *cx)
{
RootedObject barker(cx, JS_NewObject(cx, &BarkWhenTracedClass::class_, nullptr, nullptr));
if (!barker)
return nullptr;
return new Kennel(cx, barker);
}
// Do a GC, expecting |n| barkers to be finalized.
static bool
GCFinalizesNBarkers(JSContext *cx, int n)
{
int preGCTrace = BarkWhenTracedClass::traceCount;
int preGCFinalize = BarkWhenTracedClass::finalizeCount;
JS_GC(JS_GetRuntime(cx));
return (BarkWhenTracedClass::finalizeCount == preGCFinalize + n &&
BarkWhenTracedClass::traceCount > preGCTrace);
}
// PersistentRooted instances protect their contents from being recycled.
BEGIN_TEST(test_PersistentRooted)
{
BarkWhenTracedClass::reset();
Kennel *kennel = Allocate(cx);
CHECK(kennel);
// GC should be able to find our barker.
CHECK(GCFinalizesNBarkers(cx, 0));
delete(kennel);
// Now GC should not be able to find the barker.
JS_GC(JS_GetRuntime(cx));
CHECK(BarkWhenTracedClass::finalizeCount == 1);
return true;
}
END_TEST(test_PersistentRooted)
// GC should not be upset by null PersistentRooteds.
BEGIN_TEST(test_PersistentRootedNull)
{
BarkWhenTracedClass::reset();
Kennel kennel(cx);
CHECK(!kennel.obj);
JS_GC(JS_GetRuntime(cx));
CHECK(BarkWhenTracedClass::finalizeCount == 0);
return true;
}
END_TEST(test_PersistentRootedNull)
// Copy construction works.
BEGIN_TEST(test_PersistentRootedCopy)
{
BarkWhenTracedClass::reset();
Kennel *kennel = Allocate(cx);
CHECK(kennel);
CHECK(GCFinalizesNBarkers(cx, 0));
// Copy construction! AMAZING!
Kennel *newKennel = new Kennel(*kennel);
CHECK(GCFinalizesNBarkers(cx, 0));
delete(kennel);
CHECK(GCFinalizesNBarkers(cx, 0));
delete(newKennel);
// Now that kennel and nowKennel are both deallocated, GC should not be
// able to find the barker.
JS_GC(JS_GetRuntime(cx));
CHECK(BarkWhenTracedClass::finalizeCount == 1);
return true;
}
END_TEST(test_PersistentRootedCopy)
// Assignment works.
BEGIN_TEST(test_PersistentRootedAssign)
{
BarkWhenTracedClass::reset();
Kennel *kennel = Allocate(cx);
CHECK(kennel);
CHECK(GCFinalizesNBarkers(cx, 0));
// Allocate a new, empty kennel.
Kennel *kennel2 = new Kennel(cx);
// Assignment! ASTONISHING!
*kennel2 = *kennel;
// With both kennels referring to the same barker, it is held alive.
CHECK(GCFinalizesNBarkers(cx, 0));
delete(kennel2);
// The destination of the assignment alone holds the barker alive.
CHECK(GCFinalizesNBarkers(cx, 0));
// Allocate a second barker.
kennel2 = Allocate(cx);
CHECK(kennel);
*kennel = *kennel2;
// Nothing refers to the first kennel any more.
CHECK(GCFinalizesNBarkers(cx, 1));
delete(kennel);
delete(kennel2);
// Now that kennel and kennel2 are both deallocated, GC should not be
// able to find the barker.
JS_GC(JS_GetRuntime(cx));
CHECK(BarkWhenTracedClass::finalizeCount == 2);
return true;
}
END_TEST(test_PersistentRootedAssign)
#endif // defined(JSGC_USE_EXACT_ROOTING)

View File

@ -2968,6 +2968,8 @@ static const JSFunctionSpec array_methods[] = {
JS_SELF_HOSTED_FN("findIndex", "ArrayFindIndex", 1,0),
JS_SELF_HOSTED_FN("@@iterator", "ArrayValues", 0,0),
JS_SELF_HOSTED_FN("entries", "ArrayEntries", 0,0),
JS_SELF_HOSTED_FN("keys", "ArrayKeys", 0,0),
JS_FS_END
};

View File

@ -53,8 +53,8 @@
/* BSDs */
#elif defined(JS_HAVE_MACHINE_ENDIAN_H)
# include <machine/endian.h>
# include <sys/types.h>
# include <machine/endian.h>
# if defined(_BYTE_ORDER)
# if _BYTE_ORDER == _LITTLE_ENDIAN

View File

@ -1027,6 +1027,13 @@ js_FinishGC(JSRuntime *rt)
rt->gcChunkPool.expireAndFree(rt, true);
rt->gcRootsHash.clear();
rt->functionPersistentRooteds.clear();
rt->idPersistentRooteds.clear();
rt->objectPersistentRooteds.clear();
rt->scriptPersistentRooteds.clear();
rt->stringPersistentRooteds.clear();
rt->valuePersistentRooteds.clear();
}
template <typename T> struct BarrierOwner {};

View File

@ -651,7 +651,7 @@ js::Int32ToAtom<NoGC>(ExclusiveContext *cx, int32_t si);
static char *
IntToCString(ToCStringBuf *cbuf, int i, size_t *len, int base = 10)
{
unsigned u = (i < 0) ? -i : i;
unsigned u = (i < 0) ? -unsigned(i) : i;
RangedPtr<char> cp(cbuf->sbuf + ToCStringBuf::sbufSize - 1, cbuf->sbuf, ToCStringBuf::sbufSize);
char *end = cp.get();

View File

@ -260,7 +260,9 @@ ToInteger(JSContext *cx, HandleValue v, double *dp)
inline bool
SafeAdd(int32_t one, int32_t two, int32_t *res)
{
*res = one + two;
// Use unsigned for the 32-bit operation since signed overflow gets
// undefined behavior.
*res = uint32_t(one) + uint32_t(two);
int64_t ores = (int64_t)one + (int64_t)two;
return ores == (int64_t)*res;
}
@ -268,7 +270,7 @@ SafeAdd(int32_t one, int32_t two, int32_t *res)
inline bool
SafeSub(int32_t one, int32_t two, int32_t *res)
{
*res = one - two;
*res = uint32_t(one) - uint32_t(two);
int64_t ores = (int64_t)one - (int64_t)two;
return ores == (int64_t)*res;
}
@ -276,7 +278,7 @@ SafeSub(int32_t one, int32_t two, int32_t *res)
inline bool
SafeMul(int32_t one, int32_t two, int32_t *res)
{
*res = one * two;
*res = uint32_t(one) * uint32_t(two);
int64_t ores = (int64_t)one * (int64_t)two;
return ores == (int64_t)*res;
}

View File

@ -11,6 +11,7 @@
* JS public API typedefs.
*/
#include "mozilla/LinkedList.h"
#include "mozilla/NullPtr.h"
#include "mozilla/PodOperations.h"
@ -173,9 +174,12 @@ typedef bool (*JSInitCallback)(void);
typedef void
(* JSTraceDataOp)(JSTracer *trc, void *data);
void js_FinishGC(JSRuntime *rt);
namespace js {
namespace gc {
class StoreBuffer;
void MarkPersistentRootedChains(JSTracer *);
}
}
@ -224,8 +228,49 @@ struct Runtime
static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) {
return reinterpret_cast<JS::shadow::Runtime*>(rt);
}
/* Allow inlining of PersistentRooted constructors and destructors. */
private:
template <typename Referent> friend class JS::PersistentRooted;
friend void js::gc::MarkPersistentRootedChains(JSTracer *);
friend void ::js_FinishGC(JSRuntime *rt);
mozilla::LinkedList<PersistentRootedFunction> functionPersistentRooteds;
mozilla::LinkedList<PersistentRootedId> idPersistentRooteds;
mozilla::LinkedList<PersistentRootedObject> objectPersistentRooteds;
mozilla::LinkedList<PersistentRootedScript> scriptPersistentRooteds;
mozilla::LinkedList<PersistentRootedString> stringPersistentRooteds;
mozilla::LinkedList<PersistentRootedValue> valuePersistentRooteds;
/* Specializations of this return references to the appropriate list. */
template<typename Referent>
inline mozilla::LinkedList<PersistentRooted<Referent> > &getPersistentRootedList();
};
template<>
inline mozilla::LinkedList<PersistentRootedFunction>
&Runtime::getPersistentRootedList<JSFunction *>() { return functionPersistentRooteds; }
template<>
inline mozilla::LinkedList<PersistentRootedId>
&Runtime::getPersistentRootedList<jsid>() { return idPersistentRooteds; }
template<>
inline mozilla::LinkedList<PersistentRootedObject>
&Runtime::getPersistentRootedList<JSObject *>() { return objectPersistentRooteds; }
template<>
inline mozilla::LinkedList<PersistentRootedScript>
&Runtime::getPersistentRootedList<JSScript *>() { return scriptPersistentRooteds; }
template<>
inline mozilla::LinkedList<PersistentRootedString>
&Runtime::getPersistentRootedList<JSString *>() { return stringPersistentRooteds; }
template<>
inline mozilla::LinkedList<PersistentRootedValue>
&Runtime::getPersistentRootedList<Value>() { return valuePersistentRooteds; }
} /* namespace shadow */
} /* namespace JS */

View File

@ -606,7 +606,7 @@ BitLsh(JSContext *cx, HandleValue lhs, HandleValue rhs, int *out)
int32_t left, right;
if (!ToInt32(cx, lhs, &left) || !ToInt32(cx, rhs, &right))
return false;
*out = left << (right & 31);
*out = uint32_t(left) << (right & 31);
return true;
}

View File

@ -1067,9 +1067,11 @@ AddOperation(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Valu
{
if (lhs.isInt32() && rhs.isInt32()) {
int32_t l = lhs.toInt32(), r = rhs.toInt32();
double d = double(l) + double(r);
res->setNumber(d);
return true;
int32_t t;
if (JS_LIKELY(SafeAdd(l, r, &t))) {
res->setInt32(t);
return true;
}
}
if (!ToPrimitive(cx, lhs))

View File

@ -77,8 +77,7 @@ dom_quickstubs.h: dom_quickstubs.cpp
dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
$(srcdir)/qsgen.py \
$(LIBXUL_DIST)/sdk/bin/header.py \
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
$(DEPTH)/js/src/js-confdefs.h
$(LIBXUL_DIST)/sdk/bin/xpidl.py
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) \
-I$(LIBXUL_DIST)/sdk/bin \
@ -98,8 +97,7 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
event_impl_gen.conf \
$(srcdir)/dictionary_helper_gen.py \
$(LIBXUL_DIST)/sdk/bin/header.py \
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
$(DEPTH)/js/src/js-confdefs.h
$(LIBXUL_DIST)/sdk/bin/xpidl.py
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) \
-I$(LIBXUL_DIST)/sdk/bin \
@ -122,8 +120,7 @@ GeneratedEvents.h: $(srcdir)/dictionary_helper_gen.conf \
$(srcdir)/dictionary_helper_gen.py \
$(srcdir)/event_impl_gen.py \
$(LIBXUL_DIST)/sdk/bin/header.py \
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
$(DEPTH)/js/src/js-confdefs.h
$(LIBXUL_DIST)/sdk/bin/xpidl.py
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) \
-I$(LIBXUL_DIST)/sdk/bin \
@ -141,8 +138,7 @@ GeneratedEvents.cpp: DictionaryHelpers.h \
$(srcdir)/dictionary_helper_gen.py \
$(srcdir)/event_impl_gen.py \
$(LIBXUL_DIST)/sdk/bin/header.py \
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
$(DEPTH)/js/src/js-confdefs.h
$(LIBXUL_DIST)/sdk/bin/xpidl.py
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) \
-I$(LIBXUL_DIST)/sdk/bin \

View File

@ -777,11 +777,7 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
"Unexpected parent");
#endif // DEBUG
// XXX FIXME: Bug 350740
// Return here, because the postcondition for this function actually
// fails for this case, since the popups are not in a "real" frame list
// in the popup set.
return nsIFrame::kPopupList;
id = nsIFrame::kPopupList;
#endif // MOZ_XUL
} else {
NS_ASSERTION(aChildFrame->IsFloating(), "not a floated frame");
@ -792,17 +788,24 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
nsIAtom* childType = aChildFrame->GetType();
if (nsGkAtoms::menuPopupFrame == childType) {
nsIFrame* parent = aChildFrame->GetParent();
nsIFrame* firstPopup = (parent)
? parent->GetFirstChild(nsIFrame::kPopupList)
: nullptr;
NS_ASSERTION(!firstPopup || !firstPopup->GetNextSibling(),
"We assume popupList only has one child, but it has more.");
id = firstPopup == aChildFrame
? nsIFrame::kPopupList
: nsIFrame::kPrincipalList;
MOZ_ASSERT(parent, "nsMenuPopupFrame can't be the root frame");
if (parent) {
if (parent->GetType() == nsGkAtoms::popupSetFrame) {
id = nsIFrame::kPopupList;
} else {
nsIFrame* firstPopup = parent->GetFirstChild(nsIFrame::kPopupList);
MOZ_ASSERT(!firstPopup || !firstPopup->GetNextSibling(),
"We assume popupList only has one child, but it has more.");
id = firstPopup == aChildFrame
? nsIFrame::kPopupList
: nsIFrame::kPrincipalList;
}
} else {
id = nsIFrame::kPrincipalList;
}
} else if (nsGkAtoms::tableColGroupFrame == childType) {
id = nsIFrame::kColGroupList;
} else if (nsGkAtoms::tableCaptionFrame == aChildFrame->GetType()) {
} else if (nsGkAtoms::tableCaptionFrame == childType) {
id = nsIFrame::kCaptionList;
} else {
id = nsIFrame::kPrincipalList;

View File

@ -1394,7 +1394,7 @@ nsComboboxControlFrame::SetInitialChildList(ChildListID aListID,
//nsIRollupListener
//----------------------------------------------------------------------
bool
nsComboboxControlFrame::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
nsComboboxControlFrame::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp)
{
if (!mDroppedDown)
return false;

View File

@ -164,7 +164,7 @@ public:
* Hide the dropdown menu and stop capturing mouse events.
* @note This method might destroy |this|.
*/
virtual bool Rollup(uint32_t aCount, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
virtual void NotifyGeometryChange() MOZ_OVERRIDE;
/**

View File

@ -993,7 +993,8 @@ nsContainerFrame::PositionChildViews(nsIFrame* aFrame)
// Recursively walk aFrame's child frames.
// Process the additional child lists, but skip the popup list as the
// view for popups is managed by the parent. Currently only nsMenuFrame
// has a popupList and during layout will call nsMenuPopupFrame::AdjustView.
// and nsPopupSetFrame have a popupList and during layout will adjust the
// view manually to position the popup.
ChildListIterator lists(aFrame);
for (; !lists.IsDone(); lists.Next()) {
if (lists.CurrentID() == kPopupList) {

View File

@ -136,7 +136,6 @@ MOCHITEST_FILES = test_acid3_test46.html \
test_pointer-events.html \
file_position_sticky.html \
test_position_sticky.html \
test_property_database.html \
test_priority_preservation.html \
test_property_syntax_errors.html \
test_redundant_font_download.html \
@ -180,7 +179,6 @@ MOCHITEST_FILES = test_acid3_test46.html \
test_visited_pref.html \
test_visited_reftests.html \
animation_utils.js \
css_properties.js \
property_database.js \
descriptor_database.js \
unstyled.xml \
@ -217,7 +215,7 @@ MOCHITEST_FILES = test_acid3_test46.html \
viewport_units_iframe.html \
$(NULL)
_VISITED_REFTEST_FILES = \
VISITED_REFTEST_FILES = \
$(shell find $(topsrcdir)/layout/reftests/css-visited/ -name '*.html' -o -name '*.xhtml') \
$(topsrcdir)/layout/reftests/svg/pseudo-classes-02.svg \
$(topsrcdir)/layout/reftests/svg/pseudo-classes-02-ref.svg \
@ -225,17 +223,21 @@ _VISITED_REFTEST_FILES = \
$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-1-helper.svg \
$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-2-helper.svg \
$(NULL)
include $(topsrcdir)/config/rules.mk
VISITED_REFTEST_DEST = $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/css-visited/
INSTALL_TARGETS += VISITED_REFTEST
DEFINES += -DMOZILLA_INTERNAL_API
ifdef COMPILE_ENVIRONMENT
MOCHITEST_FILES += \
test_property_database.html \
css_properties.js \
$(NULL)
css_properties.js: host_ListCSSProperties$(HOST_BIN_SUFFIX) css_properties_like_longhand.js Makefile
$(RM) $@
./host_ListCSSProperties$(HOST_BIN_SUFFIX) > $@
cat $(srcdir)/css_properties_like_longhand.js >> $@
GARBAGE += css_properties.js
libs:: $(_VISITED_REFTEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/css-visited/
endif

View File

@ -282,7 +282,7 @@ public:
NS_DECL_NSIDOMEVENTLISTENER
// nsIRollupListener
virtual bool Rollup(uint32_t aCount, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
virtual bool ShouldRollupOnMouseWheelEvent() MOZ_OVERRIDE;
virtual bool ShouldConsumeOnMouseWheelEvent() MOZ_OVERRIDE;
virtual bool ShouldRollupOnMouseActivate() MOZ_OVERRIDE;

View File

@ -82,17 +82,30 @@ nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
{
if (aListID == kPopupList) {
// XXXmats this asserts because we don't implement
// GetChildList(kPopupList) so nsCSSFrameConstructor
// believes it's empty and calls us multiple times.
//NS_ASSERTION(mPopupList.IsEmpty(),
// "SetInitialChildList on non-empty child list");
NS_ASSERTION(mPopupList.IsEmpty(),
"SetInitialChildList on non-empty child list");
AddPopupFrameList(aChildList);
return NS_OK;
}
return nsBoxFrame::SetInitialChildList(aListID, aChildList);
}
const nsFrameList&
nsPopupSetFrame::GetChildList(ChildListID aListID) const
{
if (kPopupList == aListID) {
return mPopupList;
}
return nsBoxFrame::GetChildList(aListID);
}
void
nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
{
nsBoxFrame::GetChildLists(aLists);
mPopupList.AppendIfNonempty(aLists, kPopupList);
}
void
nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
@ -145,61 +158,3 @@ nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
#endif
mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
}
#ifdef DEBUG
void
nsPopupSetFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
{
ListGeneric(out, aIndent, aFlags);
// Output the children
bool outputOneList = false;
ChildListIterator lists(this);
for (; !lists.IsDone(); lists.Next()) {
if (outputOneList) {
IndentBy(out, aIndent);
}
outputOneList = true;
fprintf(out, "%s<\n", mozilla::layout::ChildListName(lists.CurrentID()));
nsFrameList::Enumerator childFrames(lists.CurrentList());
for (; !childFrames.AtEnd(); childFrames.Next()) {
nsIFrame* kid = childFrames.get();
// Verify the child frame's parent frame pointer is correct
NS_ASSERTION(kid->GetParent() == this, "bad parent frame pointer");
// Have the child frame list
kid->List(out, aIndent + 1, aFlags);
}
IndentBy(out, aIndent);
fputs(">\n", out);
}
// XXXmats the above is copy-pasted from nsContainerFrame::List which is lame,
// clean this up after bug 399111 is implemented.
if (!mPopupList.IsEmpty()) {
fputs("<\n", out);
++aIndent;
IndentBy(out, aIndent);
fputs(mozilla::layout::ChildListName(kPopupList), out);
fputs(" for ", out);
ListTag(out);
fputs(" <\n", out);
++aIndent;
for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
e.get()->List(out, aIndent, aFlags);
}
--aIndent;
IndentBy(out, aIndent);
fputs(">\n", out);
--aIndent;
IndentBy(out, aIndent);
fputs(">\n", out);
outputOneList = true;
}
if (!outputOneList) {
fputs("<>\n", out);
}
}
#endif

View File

@ -36,6 +36,9 @@ public:
NS_IMETHOD SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) MOZ_OVERRIDE;
virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
// Used to destroy our popup frames.
@ -44,7 +47,6 @@ public:
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
#ifdef DEBUG
void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
{
return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult);

View File

@ -180,7 +180,7 @@ nsXULPopupManager::GetInstance()
}
bool
nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
nsXULPopupManager::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp)
{
bool consume = false;
@ -202,6 +202,20 @@ nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
}
consume = item->Frame()->ConsumeOutsideClicks();
// If the click was over the anchor, always consume the click. This way,
// clicking on a menu doesn't reopen the menu.
if (!consume && pos) {
nsCOMPtr<nsIContent> anchor = item->Frame()->GetAnchor();
if (anchor && anchor->GetPrimaryFrame()) {
// It's possible that some other element is above the anchor at the same
// position, but the only thing that would happen is that the mouse
// event will get consumed, so here only a quick coordinates check is
// done rather than a slower complete check of what is at that location.
if (anchor->GetPrimaryFrame()->GetScreenRect().Contains(*pos)) {
consume = true;
}
}
}
// if a number of popups to close has been specified, determine the last
// popup to close
@ -2005,7 +2019,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
#endif
// close popups or deactivate menubar when Tab or F10 are pressed
if (aTopVisibleMenuItem) {
Rollup(0, nullptr);
Rollup(0, nullptr, nullptr);
} else if (mActiveMenuBar) {
mActiveMenuBar->MenuClosed();
}
@ -2240,7 +2254,7 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent)
// The access key just went down and no other
// modifiers are already down.
if (mPopups)
Rollup(0, nullptr);
Rollup(0, nullptr, nullptr);
else if (mActiveMenuBar)
mActiveMenuBar->MenuClosed();
}

View File

@ -421,6 +421,9 @@ pref("ui.scrollToClick", 0);
pref("accessibility.tabfocus_applies_to_xul", true);
#endif
// provide ability to turn on support for canvas focus rings
pref("canvas.focusring.enabled", false);
// We want the ability to forcibly disable platform a11y, because
// some non-a11y-related components attempt to bring it up. See bug
// 538530 for details about Windows; we have a pref here that allows it

View File

@ -404,7 +404,7 @@ class MozbuildObject(ProcessExecutionMixin):
args = self._make_path(force_pymake=force_pymake)
if directory:
args.extend(['-C', directory])
args.extend(['-C', directory.replace(os.sep, '/')])
if filename:
args.extend(['-f', filename])

View File

@ -1387,6 +1387,10 @@ NS_IMETHODIMP
nsNSSCertificateDB::ConstructX509FromBase64(const char *base64,
nsIX509Cert **_retval)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ENSURE_ARG_POINTER(_retval);
// sure would be nice to have a smart pointer class for PL_ allocations
@ -1410,10 +1414,6 @@ nsNSSCertificateDB::ConstructX509FromBase64(const char *base64,
lengthDER--;
}
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
SECItem secitem_cert;
secitem_cert.type = siDERCertBuffer;

View File

@ -16,6 +16,12 @@ int min_log_level = 0;
namespace logging
{
DcheckState g_dcheck_state = DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
DcheckState get_dcheck_state() {
return g_dcheck_state;
}
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
int ctr) :
line_(line)

View File

@ -184,6 +184,7 @@
"dom/tests/mochitest/geolocation/test_allowWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_cachedPosition.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_clearWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_errorcheck.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "Don't run modal tests on Android",
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html": "TIMED_OUT",

View File

@ -254,6 +254,7 @@
"dom/tests/mochitest/geolocation/test_allowWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_cachedPosition.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_clearWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_errorcheck.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "Don't run modal tests on Android",
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html": "TIMED_OUT",

View File

@ -100,6 +100,7 @@
"content/base/test/test_child_process_shutdown_message.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
"content/base/test/test_messagemanager_assertpermission.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
"content/canvas/test/test_canvas_focusring.html":"specialpowers.wrap",
"content/html/content/test/test_formSubmission.html":"NS_ERROR_FILE_TARGET_DOES_NOT_EXIST",
@ -353,6 +354,7 @@
"dom/tests/mochitest/geolocation/test_cancelWatch.html":"",
"dom/tests/mochitest/geolocation/test_clearWatch.html":"",
"dom/tests/mochitest/geolocation/test_clearWatch_invalid.html":"",
"dom/tests/mochitest/geolocation/test_errorcheck.html": "",
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "showmodaldialog",
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html":"",
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html":"",

View File

@ -3,9 +3,6 @@
# 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/.
CHROME_DEPS = buildconfig.html
USE_RCS_MK := 1
include $(topsrcdir)/config/makefiles/makeutils.mk

View File

@ -313,7 +313,7 @@
</binding>
<binding id="arrowpanel" extends="chrome://global/content/bindings/popup.xml#panel">
<content flip="both" side="top" position="bottomcenter topleft">
<content flip="both" side="top" position="bottomcenter topleft" consumeoutsideclicks="false">
<xul:box anonid="container" class="panel-arrowcontainer" flex="1"
xbl:inherits="side,panelopen">
<xul:box anonid="arrowbox" class="panel-arrowbox">

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