Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-06-10 15:27:48 +02:00
Родитель 3a7aff3110 6aa1662524
Коммит 13d8c8bc5a
179 изменённых файлов: 2755 добавлений и 1195 удалений

Просмотреть файл

@ -455,7 +455,8 @@ DocAccessible::Shutdown()
mChildDocuments.Clear();
// XXX thinking about ordering?
if (IPCAccessibilityActive()) {
if (mIPCDoc) {
MOZ_ASSERT(IPCAccessibilityActive());
mIPCDoc->Shutdown();
MOZ_ASSERT(!mIPCDoc);
}

1
aclocal.m4 поставляемый
Просмотреть файл

@ -33,6 +33,7 @@ builtin(include, build/autoconf/winsdk.m4)dnl
builtin(include, build/autoconf/icu.m4)dnl
builtin(include, build/autoconf/ffi.m4)dnl
builtin(include, build/autoconf/clang-plugin.m4)dnl
builtin(include, build/autoconf/alloc.m4)dnl
MOZ_PROG_CHECKMSYS()

Просмотреть файл

@ -975,6 +975,7 @@ pref("browser.safebrowsing.enabled", true);
pref("browser.safebrowsing.malware.enabled", true);
pref("browser.safebrowsing.downloads.enabled", true);
pref("browser.safebrowsing.downloads.remote.enabled", true);
pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
pref("browser.safebrowsing.debug", false);
pref("browser.safebrowsing.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");

Просмотреть файл

@ -692,7 +692,7 @@
if (this.mTab.hasAttribute("busy")) {
this.mTab.removeAttribute("busy");
this.mTabBrowser._tabAttrModified(this.mTab);
this.mTabBrowser._tabAttrModified(this.mTab, ["busy"]);
if (!this.mTab.selected)
this.mTab.setAttribute("unread", "true");
}
@ -892,7 +892,7 @@
aTab.setAttribute("image", sizedIconUrl);
else
aTab.removeAttribute("image");
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["image"]);
}
this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]);
@ -1167,8 +1167,8 @@
});
this.mCurrentTab.dispatchEvent(event);
this._tabAttrModified(oldTab);
this._tabAttrModified(this.mCurrentTab);
this._tabAttrModified(oldTab, ["selected"]);
this._tabAttrModified(this.mCurrentTab, ["selected"]);
if (oldBrowser != newBrowser &&
oldBrowser.docShell &&
@ -1300,14 +1300,18 @@
<method name="_tabAttrModified">
<parameter name="aTab"/>
<parameter name="aChanged"/>
<body><![CDATA[
if (aTab.closing)
return;
// This event should be dispatched when any of these attributes change:
// label, crop, busy, image, selected
var event = document.createEvent("Events");
event.initEvent("TabAttrModified", true, false);
let event = new CustomEvent("TabAttrModified", {
bubbles: true,
cancelable: false,
detail: {
changed: aChanged,
}
});
aTab.dispatchEvent(event);
]]></body>
</method>
@ -1318,7 +1322,7 @@
<![CDATA[
aTab.label = this.mStringBundle.getString("tabs.connecting");
aTab.crop = "end";
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["label", "crop"]);
]]>
</body>
</method>
@ -1363,7 +1367,7 @@
aTab.label = title;
aTab.crop = crop;
this._tabAttrModified(aTab);
this._tabAttrModified(aTab, ["label", "crop"]);
if (aTab.selected)
this.updateTitlebar();
@ -2449,7 +2453,7 @@
var isBusy = aOtherTab.hasAttribute("busy");
if (isBusy) {
aOurTab.setAttribute("busy", "true");
this._tabAttrModified(aOurTab);
this._tabAttrModified(aOurTab, ["busy"]);
if (aOurTab.selected)
this.mIsBusy = true;
}

53
build/autoconf/alloc.m4 Normal file
Просмотреть файл

@ -0,0 +1,53 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl Check for the existence of various allocation headers/functions
AC_DEFUN([MOZ_CHECK_ALLOCATOR],[
MALLOC_HEADERS="malloc.h malloc_np.h malloc/malloc.h sys/malloc.h"
MALLOC_H=
for file in $MALLOC_HEADERS; do
MOZ_CHECK_HEADER($file, [MALLOC_H=$file])
if test "$MALLOC_H" != ""; then
AC_DEFINE_UNQUOTED(MALLOC_H, <$MALLOC_H>)
break
fi
done
MOZ_CHECK_HEADERS(alloca.h)
AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);],
[return malloc_usable_size(0);],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
dnl In newer bionic headers, valloc is built but not defined,
dnl so we check more carefully here.
AC_MSG_CHECKING([for valloc in malloc.h])
AC_EGREP_HEADER(valloc, malloc.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
AC_MSG_CHECKING([for valloc in unistd.h])
AC_EGREP_HEADER(valloc, unistd.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
])

Просмотреть файл

@ -47,6 +47,7 @@ SEARCH_PATHS = [
'other-licenses/ply',
'xpcom/idl-parser',
'testing',
'testing/tools/autotry',
'testing/taskcluster',
'testing/xpcshell',
'testing/web-platform',

Просмотреть файл

@ -3399,52 +3399,6 @@ if test -n "$MOZ_LINKER" -a "$OS_TARGET" = "Android"; then
fi
fi
dnl Check for the existence of various allocation headers/functions
MALLOC_HEADERS="malloc.h malloc_np.h malloc/malloc.h sys/malloc.h"
MALLOC_H=
for file in $MALLOC_HEADERS; do
MOZ_CHECK_HEADER($file, [MALLOC_H=$file])
if test "$MALLOC_H" != ""; then
AC_DEFINE_UNQUOTED(MALLOC_H, <$MALLOC_H>)
break
fi
done
MOZ_CHECK_HEADERS(alloca.h)
AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);],
[return malloc_usable_size(0);],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
dnl In newer bionic headers, valloc is built but not defined,
dnl so we check more carefully here.
AC_MSG_CHECKING([for valloc in malloc.h])
AC_EGREP_HEADER(valloc, malloc.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
AC_MSG_CHECKING([for valloc in unistd.h])
AC_EGREP_HEADER(valloc, unistd.h,
AC_DEFINE(HAVE_VALLOC)
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
dnl See if compiler supports some gcc-style attributes
AC_CACHE_CHECK(for __attribute__((always_inline)),
@ -3479,6 +3433,8 @@ fi
AC_HAVE_FUNCS(localeconv)
fi # ! SKIP_COMPILER_CHECKS
MOZ_CHECK_ALLOCATOR
TARGET_XPCOM_ABI=
if test -n "${CPU_ARCH}" -a -n "${TARGET_COMPILER_ABI}"; then
TARGET_XPCOM_ABI="${CPU_ARCH}-${TARGET_COMPILER_ABI}"

Просмотреть файл

@ -11196,12 +11196,8 @@ ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
void
nsDocument::ExitFullscreen(nsIDocument* aDoc)
{
// Unlock the pointer, if it's locked.
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
// Unlock the pointer
UnlockPointer();
if (aDoc) {
ExitFullscreenInDocTree(aDoc);
@ -11258,11 +11254,7 @@ nsDocument::RestorePreviousFullScreenState()
}
// If fullscreen mode is updated the pointer should be unlocked
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
UnlockPointer();
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
@ -11271,7 +11263,6 @@ nsDocument::RestorePreviousFullScreenState()
while (doc != this) {
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
UnlockPointer();
DispatchFullScreenChange(doc);
doc = doc->GetParentDocument();
}
@ -11280,7 +11271,6 @@ nsDocument::RestorePreviousFullScreenState()
NS_ASSERTION(doc == this, "Must have reached this doc.");
while (doc != nullptr) {
static_cast<nsDocument*>(doc)->FullScreenStackPop();
UnlockPointer();
DispatchFullScreenChange(doc);
if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
// Full-screen stack in document is empty. Go back up to the parent
@ -11666,19 +11656,10 @@ nsDocument::RequestFullScreen(Element* aElement,
// Remember the root document, so that if a full-screen document is hidden
// we can reset full-screen state in the remaining visible full-screen documents.
nsIDocument* fullScreenRootDoc = nsContentUtils::GetRootDocument(this);
if (fullScreenRootDoc->IsFullScreenDoc()) {
// A document is already in fullscreen, unlock the mouse pointer
// before setting a new document to fullscreen
UnlockPointer();
}
// If a document is already in fullscreen, then unlock the mouse pointer
// before setting a new document to fullscreen
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (pointerLockedElement) {
UnlockPointer();
}
UnlockPointer();
// Process options -- in this case, just HMD
if (aOptions.mVRHMDDevice) {

Просмотреть файл

@ -33,7 +33,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override;
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;

Просмотреть файл

@ -35,22 +35,6 @@ WebGL1Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
return false;
}
/** Buffer and Target validation for BindBuffer */
bool
WebGL1Context::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
if (buffer->HasEverBeenBound() && target != buffer->Target()) {
ErrorInvalidOperation("%s: buffer already bound to a different target", info);
return false;
}
return true;
}
bool
WebGL1Context::ValidateBufferUsageEnum(GLenum usage, const char* info)
{

Просмотреть файл

@ -365,10 +365,11 @@ private:
GLsizei width, GLsizei height, GLsizei depth,
const char* info);
// CreateVertexArrayImpl is assumed to be infallible.
virtual WebGLVertexArray* CreateVertexArrayImpl() override;
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
virtual bool ValidateBufferTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override;
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;

Просмотреть файл

@ -45,36 +45,6 @@ WebGL2Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
}
}
bool
WebGL2Context::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
switch (target) {
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
return true;
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
return !buffer->HasEverBeenBound() ||
buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
return !buffer->HasEverBeenBound() ||
buffer->Target() != LOCAL_GL_ELEMENT_ARRAY_BUFFER;
}
ErrorInvalidOperation("%s: buffer already bound to a incompatible target %s",
info, EnumName(buffer->Target().get()));
return false;
}
bool
WebGL2Context::ValidateBufferUsageEnum(GLenum usage, const char* info)
{
@ -123,7 +93,7 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
if (!readBuffer)
return ErrorInvalidOperation("copyBufferSubData: No buffer bound to readTarget");
const WebGLBuffer* writeBuffer = writeBufferSlot.get();
WebGLBuffer* writeBuffer = writeBufferSlot.get();
if (!writeBuffer)
return ErrorInvalidOperation("copyBufferSubData: No buffer bound to writeTarget");
@ -145,8 +115,27 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
return;
}
WebGLBuffer::Kind readType = readBuffer->Content();
WebGLBuffer::Kind writeType = writeBuffer->Content();
if (readType != WebGLBuffer::Kind::Undefined &&
writeType != WebGLBuffer::Kind::Undefined &&
writeType != readType)
{
ErrorInvalidOperation("copyBufferSubData: Can't copy %s data to %s data",
(readType == WebGLBuffer::Kind::OtherData) ? "other" : "element",
(writeType == WebGLBuffer::Kind::OtherData) ? "other" : "element");
return;
}
WebGLContextUnchecked::CopyBufferSubData(readTarget, writeTarget, readOffset,
writeOffset, size);
if (writeType == WebGLBuffer::Kind::Undefined) {
writeBuffer->BindTo(
(readType == WebGLBuffer::Kind::OtherData) ? LOCAL_GL_ARRAY_BUFFER
: LOCAL_GL_ELEMENT_ARRAY_BUFFER);
}
}
void
@ -155,7 +144,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
{
if (IsContextLost())
return;
// For the WebGLBuffer bound to the passed target, read
// returnedData.byteLength bytes from the buffer starting at byte
// offset offset and write them to returnedData.
@ -168,7 +157,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
// If offset is less than zero, an INVALID_VALUE error is
// generated.
if (offset < 0)
return ErrorInvalidValue("getBufferSubData: negative offset");
return ErrorInvalidValue("getBufferSubData: negative offset");
// If returnedData is null then an INVALID_VALUE error is
// generated.
@ -179,7 +168,7 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
WebGLBuffer* boundBuffer = bufferSlot.get();
if (!boundBuffer)
return ErrorInvalidOperation("getBufferSubData: no buffer bound");
// If offset + returnedData.byteLength would extend beyond the end
// of the buffer an INVALID_VALUE error is generated.
const dom::ArrayBuffer& data = maybeData.Value();

Просмотреть файл

@ -54,7 +54,8 @@ WebGL2Context::IsSampler(WebGLSampler* sampler)
if (sampler->IsDeleted())
return false;
return !sampler->HasEverBeenBound();
MakeContextCurrent();
return gl->fIsSampler(sampler->mGLName);
}
void

Просмотреть файл

@ -60,7 +60,7 @@ WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf)
return false;
MakeContextCurrent();
return gl->fIsTransformFeedback(tf->GLName());
return gl->fIsTransformFeedback(tf->mGLName);
}
void
@ -84,11 +84,8 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
if (tf && tf->IsDeleted())
return ErrorInvalidOperation("bindTransformFeedback: Attempt to bind deleted id");
if (tf)
tf->BindTo(LOCAL_GL_TRANSFORM_FEEDBACK);
MakeContextCurrent();
gl->fBindTransformFeedback(target, tf ? tf->GLName() : 0);
gl->fBindTransformFeedback(target, tf ? tf->mGLName : 0);
if (tf)
mBoundTransformFeedback = tf;
else

Просмотреть файл

@ -5,16 +5,17 @@
#include "WebGL2Context.h"
#include "GLContext.h"
#include "WebGLVertexArrayObject.h"
using namespace mozilla;
using namespace mozilla::dom;
namespace mozilla {
// -------------------------------------------------------------------------
// Vertex Array Object
// TODO(djg): Implemented in WebGLContext
/*
already_AddRefed<WebGLVertexArrayObject> CreateVertexArray();
void DeleteVertexArray(WebGLVertexArrayObject* vertexArray);
bool IsVertexArray(WebGLVertexArrayObject* vertexArray);
void BindVertexArray(WebGLVertexArrayObject* vertexArray);
*/
WebGLVertexArray*
WebGL2Context::CreateVertexArrayImpl()
{
return dom::WebGLVertexArrayObject::Create(this);
}
} // namespace mozilla

Просмотреть файл

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 4; 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/. */
#ifndef WEBGLBINDABLENAME_H_
#define WEBGLBINDABLENAME_H_
#include "WebGLTypes.h"
#include "GLDefs.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Assertions.h"
namespace mozilla {
/** Represents a binding to a GL binding point
*/
template<typename T>
class WebGLBindable
{
public:
WebGLBindable() : mTarget(LOCAL_GL_NONE) { }
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
void BindTo(T target) {
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
MOZ_ASSERT(!HasEverBeenBound() || mTarget == target, "Rebinding is illegal.");
bool targetChanged = (target != mTarget);
mTarget = target;
if (targetChanged)
OnTargetChanged();
}
T Target() const {
MOZ_ASSERT(HasEverBeenBound());
return mTarget;
}
protected:
//! Called after mTarget has been changed by BindTo(target).
virtual void OnTargetChanged() {}
T mTarget;
};
/** Represents a GL name that can be bound to a target.
*/
template<typename T>
class WebGLBindableName
: public WebGLBindable<T>
{
public:
explicit WebGLBindableName(GLuint aName)
: WebGLBindable<T>()
, mGLName(aName)
{ }
GLuint GLName() const { return mGLName; }
protected:
const GLuint mGLName;
};
} // namespace mozilla
#endif // !WEBGLBINDABLENAME_H_

Просмотреть файл

@ -13,8 +13,9 @@
namespace mozilla {
WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf)
: WebGLBindableName<BufferBinding>(buf)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(buf)
, mContent(Kind::Undefined)
, mByteLength(0)
{
mContext->mBuffers.insertBack(this);
@ -25,6 +26,34 @@ WebGLBuffer::~WebGLBuffer()
DeleteOnce();
}
void
WebGLBuffer::BindTo(GLenum target)
{
switch (target) {
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
mContent = Kind::ElementArray;
if (!mCache)
mCache = new WebGLElementArrayCache;
break;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
mContent = Kind::OtherData;
break;
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
/* Do nothing. Doesn't set the type of the buffer contents. */
break;
default:
MOZ_CRASH();
}
}
void
WebGLBuffer::Delete()
{
@ -35,18 +64,11 @@ WebGLBuffer::Delete()
LinkedListElement<WebGLBuffer>::remove(); // remove from mContext->mBuffers
}
void
WebGLBuffer::OnTargetChanged()
{
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
mCache = new WebGLElementArrayCache;
}
bool
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr,
size_t bufferSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
if (mContent == Kind::ElementArray)
return mCache->BufferData(ptr, bufferSizeInBytes);
return true;
@ -56,7 +78,7 @@ void
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr,
size_t updateSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
if (mContent == Kind::ElementArray)
mCache->BufferSubData(pos, ptr, updateSizeInBytes);
}

Просмотреть файл

@ -10,7 +10,6 @@
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "WebGLTypes.h"
@ -21,14 +20,23 @@ class WebGLElementArrayCache;
class WebGLBuffer final
: public nsWrapperCache
, public WebGLBindableName<BufferBinding>
, public WebGLRefCountedObject<WebGLBuffer>
, public LinkedListElement<WebGLBuffer>
, public WebGLContextBoundObject
{
public:
enum class Kind {
Undefined,
ElementArray,
OtherData
};
explicit WebGLBuffer(WebGLContext* webgl, GLuint buf);
void BindTo(GLenum target);
Kind Content() const { return mContent; }
void Delete();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
@ -52,14 +60,15 @@ public:
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
protected:
~WebGLBuffer();
virtual void OnTargetChanged() override;
Kind mContent;
WebGLsizeiptr mByteLength;
nsAutoPtr<WebGLElementArrayCache> mCache;
};

Просмотреть файл

@ -1880,7 +1880,7 @@ WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
: gl::OriginPos::TopLeft;
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(),
srcImage->GetSize(),
tex->GLName(),
tex->mGLName,
texImageTarget.get(),
destOrigin);
if (ok) {

Просмотреть файл

@ -939,6 +939,8 @@ protected:
WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
GLuint index);
GLenum GetCurrentBinding(WebGLBuffer* buffer) const;
// -----------------------------------------------------------------------------
// Queries (WebGL2ContextQueries.cpp)
protected:
@ -1390,10 +1392,12 @@ private:
private:
// -------------------------------------------------------------------------
// Context customization points
virtual WebGLVertexArray* CreateVertexArrayImpl();
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0;
virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0;
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) = 0;
virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info);
virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) = 0;
virtual bool ValidateQueryTarget(GLenum usage, const char* info) = 0;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0;

Просмотреть файл

@ -20,24 +20,7 @@ WebGLContext::UpdateBoundBuffer(GLenum target, WebGLBuffer* buffer)
if (!buffer)
return;
/* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
*
* In the WebGL 2 API, buffers have their WebGL buffer type
* initially set to undefined. Calling bindBuffer, bindBufferRange
* or bindBufferBase with the target argument set to any buffer
* binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will
* then set the WebGL buffer type of the buffer being bound
* according to the table above.
*
* Any call to one of these functions which attempts to bind a
* WebGLBuffer that has the element array WebGL buffer type to a
* binding point that falls under other data, or bind a
* WebGLBuffer which has the other data WebGL buffer type to
* ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error,
* and the state of the binding point will remain untouched.
*/
if (target != LOCAL_GL_COPY_READ_BUFFER && target != LOCAL_GL_COPY_WRITE_BUFFER)
buffer->BindTo(target);
buffer->BindTo(target);
}
void
@ -410,12 +393,50 @@ WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
if (!buffer || buffer->IsDeleted())
return;
if (mBoundArrayBuffer == buffer)
BindBuffer(LOCAL_GL_ARRAY_BUFFER, static_cast<WebGLBuffer*>(nullptr));
// TODO: Extract this into a helper function?
if (mBoundArrayBuffer == buffer) {
WebGLContextUnchecked::BindBuffer(LOCAL_GL_ARRAY_BUFFER, nullptr);
mBoundArrayBuffer = nullptr;
}
if (mBoundVertexArray->mElementArrayBuffer == buffer) {
BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
static_cast<WebGLBuffer*>(nullptr));
WebGLContextUnchecked::BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, nullptr);
mBoundVertexArray->mElementArrayBuffer = nullptr;
}
// WebGL binding points
if (IsWebGL2()) {
if (mBoundCopyReadBuffer == buffer)
mBoundCopyReadBuffer = nullptr;
if (mBoundCopyWriteBuffer == buffer)
mBoundCopyWriteBuffer = nullptr;
if (mBoundPixelPackBuffer == buffer)
mBoundPixelPackBuffer = nullptr;
if (mBoundPixelUnpackBuffer == buffer)
mBoundPixelUnpackBuffer = nullptr;
if (mBoundTransformFeedbackBuffer == buffer)
mBoundTransformFeedbackBuffer = nullptr;
if (mBoundUniformBuffer == buffer)
mBoundUniformBuffer = nullptr;
const size_t xfBufferCount = mBoundTransformFeedbackBuffers.Length();
for (size_t n = 0; n < xfBufferCount; n++) {
if (mBoundTransformFeedbackBuffers[n] == buffer) {
mBoundTransformFeedbackBuffers[n] = nullptr;
}
}
const size_t uniformBufferCount = mBoundUniformBuffers.Length();
for (size_t n = 0; n < uniformBufferCount; n++) {
if (mBoundUniformBuffers[n] == buffer) {
mBoundUniformBuffers[n] = nullptr;
}
}
}
for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
@ -435,9 +456,89 @@ WebGLContext::IsBuffer(WebGLBuffer* buffer)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isBuffer", buffer) &&
!buffer->IsDeleted() &&
buffer->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isBuffer", buffer))
return false;
if (buffer->IsDeleted())
return false;
MakeContextCurrent();
return gl->fIsBuffer(buffer->mGLName);
}
bool
WebGLContext::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
const char* info)
{
if (!buffer)
return true;
/* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
*
* In the WebGL 2 API, buffers have their WebGL buffer type
* initially set to undefined. Calling bindBuffer, bindBufferRange
* or bindBufferBase with the target argument set to any buffer
* binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will
* then set the WebGL buffer type of the buffer being bound
* according to the table above.
*
* Any call to one of these functions which attempts to bind a
* WebGLBuffer that has the element array WebGL buffer type to a
* binding point that falls under other data, or bind a
* WebGLBuffer which has the other data WebGL buffer type to
* ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error,
* and the state of the binding point will remain untouched.
*/
GLenum boundTo = GetCurrentBinding(buffer);
if (boundTo != LOCAL_GL_NONE) {
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
boundTo != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
{
ErrorInvalidOperation("Can't bind buffer to TRANSFORM_FEEDBACK_BUFFER as the "
"buffer is already bound to another bind point.");
return false;
}
else if (target != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
boundTo == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
{
ErrorInvalidOperation("Can't bind buffer to bind point as it is currently "
"bound to TRANSFORM_FEEDBACK_BUFFER.");
return false;
}
}
WebGLBuffer::Kind content = buffer->Content();
if (content == WebGLBuffer::Kind::Undefined)
return true;
switch (target) {
case LOCAL_GL_COPY_READ_BUFFER:
case LOCAL_GL_COPY_WRITE_BUFFER:
return true;
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
if (content == WebGLBuffer::Kind::ElementArray)
return true;
break;
case LOCAL_GL_ARRAY_BUFFER:
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
case LOCAL_GL_UNIFORM_BUFFER:
if (content == WebGLBuffer::Kind::OtherData)
return true;
break;
default:
MOZ_CRASH();
}
ErrorInvalidOperation("%s: buffer already contains %s data.", info,
content == WebGLBuffer::Kind::OtherData ? "other" : "element");
return false;
}
bool
@ -510,6 +611,37 @@ WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index)
}
}
GLenum
WebGLContext::GetCurrentBinding(WebGLBuffer* buffer) const
{
if (mBoundArrayBuffer == buffer)
return LOCAL_GL_ARRAY_BUFFER;
if (mBoundCopyReadBuffer == buffer)
return LOCAL_GL_COPY_READ_BUFFER;
if (mBoundCopyWriteBuffer == buffer)
return LOCAL_GL_COPY_WRITE_BUFFER;
if (mBoundPixelPackBuffer == buffer)
return LOCAL_GL_PIXEL_PACK_BUFFER;
if (mBoundPixelUnpackBuffer == buffer)
return LOCAL_GL_PIXEL_UNPACK_BUFFER;
if (mBoundTransformFeedbackBuffer == buffer ||
mBoundTransformFeedbackBuffers.Contains(buffer)) {
return LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER;
}
if (mBoundUniformBuffer == buffer ||
mBoundUniformBuffers.Contains(buffer)) {
return LOCAL_GL_UNIFORM_BUFFER;
}
return LOCAL_GL_NONE;
}
GLenum
WebGLContext::CheckedBufferData(GLenum target, GLsizeiptr size,
const GLvoid* data, GLenum usage)

Просмотреть файл

@ -600,7 +600,7 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
}
GLenum error = GetAndFlushUnderlyingGLErrors();
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
// note that we do this error checking and early return AFTER having restored the buffer binding above
if (error) {
@ -626,7 +626,7 @@ WebGLContext::UndoFakeVertexAttrib0()
if (mBoundVertexArray->HasAttrib(0) && mBoundVertexArray->mAttribs[0].buf) {
const WebGLVertexAttribData& attrib0 = mBoundVertexArray->mAttribs[0];
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->GLName());
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->mGLName);
if (attrib0.integer) {
gl->fVertexAttribIPointer(0,
attrib0.size,
@ -645,7 +645,7 @@ WebGLContext::UndoFakeVertexAttrib0()
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0);
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
}
WebGLContextFakeBlackStatus
@ -737,11 +737,11 @@ WebGLContext::UnbindFakeBlackTextures()
for (int32_t i = 0; i < mGLMaxTextureUnits; ++i) {
if (mBound2DTextures[i] && mBound2DTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->GLName());
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->mGLName);
}
if (mBoundCubeMapTextures[i] && mBoundCubeMapTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) {
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->GLName());
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->mGLName);
}
}

Просмотреть файл

@ -159,9 +159,11 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
if (!wfb) {
gl->fBindFramebuffer(target, 0);
} else {
wfb->BindTo(target);
GLuint framebuffername = wfb->GLName();
GLuint framebuffername = wfb->mGLName;
gl->fBindFramebuffer(target, framebuffername);
#ifdef ANDROID
wfb->mIsFB = true;
#endif
}
switch (target) {
@ -196,15 +198,15 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb)
if (wrb && wrb->IsDeleted())
return;
if (wrb)
wrb->BindTo(target);
MakeContextCurrent();
// Sometimes we emulate renderbuffers (depth-stencil emu), so there's not
// always a 1-1 mapping from `wrb` to GL name. Just have `wrb` handle it.
if (wrb) {
wrb->BindRenderbuffer();
#ifdef ANDROID
wrb->mIsRB = true;
#endif
} else {
gl->fBindRenderbuffer(target, 0);
}
@ -737,7 +739,7 @@ WebGLContext::DeleteTexture(WebGLTexture* tex)
(mBound3DTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_3D))
{
ActiveTexture(LOCAL_GL_TEXTURE0 + i);
BindTexture(tex->Target().get(), nullptr);
BindTexture(tex->Target(), nullptr);
}
}
ActiveTexture(LOCAL_GL_TEXTURE0 + activeTexture);
@ -1691,9 +1693,22 @@ WebGLContext::IsFramebuffer(WebGLFramebuffer* fb)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isFramebuffer", fb) &&
!fb->IsDeleted() &&
fb->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isFramebuffer", fb))
return false;
if (fb->IsDeleted())
return false;
#ifdef ANDROID
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::AndroidEmulator)
{
return fb->mIsFB;
}
#endif
MakeContextCurrent();
return gl->fIsFramebuffer(fb->mGLName);
}
bool
@ -1711,9 +1726,22 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer* rb)
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isRenderBuffer", rb) &&
!rb->IsDeleted() &&
rb->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isRenderBuffer", rb))
return false;
if (rb->IsDeleted())
return false;
#ifdef ANDROID
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::AndroidEmulator)
{
return rb->mIsRB;
}
#endif
MakeContextCurrent();
return gl->fIsRenderbuffer(rb->PrimaryGLName());
}
bool

Просмотреть файл

@ -126,8 +126,7 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed()
buffer;
buffer = buffer->getNext())
{
if (buffer->HasEverBeenBound() &&
buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
if (buffer->Content() == WebGLBuffer::Kind::ElementArray) {
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
}
}

Просмотреть файл

@ -194,21 +194,38 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
if (IsWebGL2()) {
switch (pname) {
case LOCAL_GL_MAX_SAMPLES:
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
GLint val;
gl->fGetIntegerv(pname, &val);
return JS::NumberValue(uint32_t(val));
}
case LOCAL_GL_MAX_SAMPLES:
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE:
case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
GLint val;
gl->fGetIntegerv(pname, &val);
return JS::NumberValue(uint32_t(val));
}
case LOCAL_GL_TEXTURE_BINDING_3D: {
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
}
case LOCAL_GL_TEXTURE_BINDING_3D:
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
case LOCAL_GL_COPY_READ_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
}
}
@ -533,13 +550,6 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
}
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
if (!IsWebGL2()) {
break;
}
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
}
case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv);
}

Просмотреть файл

@ -24,21 +24,32 @@ void
WebGLContextUnchecked::BindBuffer(GLenum target, WebGLBuffer* buffer)
{
gl->MakeCurrent();
gl->fBindBuffer(target, buffer ? buffer->GLName() : 0);
gl->fBindBuffer(target, buffer ? buffer->mGLName : 0);
}
void
WebGLContextUnchecked::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
{
gl->MakeCurrent();
gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0);
gl->fBindBufferBase(target, index, buffer ? buffer->mGLName : 0);
}
void
WebGLContextUnchecked::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size)
{
gl->MakeCurrent();
gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size);
#ifdef XP_MACOSX
if (buffer && buffer->Content() == WebGLBuffer::Kind::Undefined &&
gl->WorkAroundDriverBugs())
{
// BindBufferRange will fail if the buffer's contents is undefined.
// Bind so driver initializes the buffer.
gl->fBindBuffer(target, buffer->mGLName);
}
#endif
gl->fBindBufferRange(target, index, buffer ? buffer->mGLName : 0, offset, size);
}
void
@ -56,9 +67,7 @@ void
WebGLContextUnchecked::BindSampler(GLuint unit, WebGLSampler* sampler)
{
gl->MakeCurrent();
gl->fBindSampler(unit, sampler ? sampler->GLName() : 0);
if (sampler)
sampler->BindTo(LOCAL_GL_SAMPLER_BINDING);
gl->fBindSampler(unit, sampler ? sampler->mGLName : 0);
}
GLint
@ -69,7 +78,7 @@ WebGLContextUnchecked::GetSamplerParameteriv(WebGLSampler* sampler,
GLint param = 0;
gl->MakeCurrent();
gl->fGetSamplerParameteriv(sampler->GLName(), pname, &param);
gl->fGetSamplerParameteriv(sampler->mGLName, pname, &param);
return param;
}
@ -82,7 +91,7 @@ WebGLContextUnchecked::GetSamplerParameterfv(WebGLSampler* sampler,
GLfloat param = 0.0f;
gl->MakeCurrent();
gl->fGetSamplerParameterfv(sampler->GLName(), pname, &param);
gl->fGetSamplerParameterfv(sampler->mGLName, pname, &param);
return param;
}
@ -93,7 +102,7 @@ WebGLContextUnchecked::SamplerParameteri(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteri(sampler->GLName(), pname, param);
gl->fSamplerParameteri(sampler->mGLName, pname, param);
}
void
@ -103,7 +112,7 @@ WebGLContextUnchecked::SamplerParameteriv(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteriv(sampler->GLName(), pname, param);
gl->fSamplerParameteriv(sampler->mGLName, pname, param);
}
void
@ -113,7 +122,7 @@ WebGLContextUnchecked::SamplerParameterf(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterf(sampler->GLName(), pname, param);
gl->fSamplerParameterf(sampler->mGLName, pname, param);
}
void
@ -123,7 +132,7 @@ WebGLContextUnchecked::SamplerParameterfv(WebGLSampler* sampler,
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterfv(sampler->GLName(), pname, param);
gl->fSamplerParameterfv(sampler->mGLName, pname, param);
}
} // namespace mozilla

Просмотреть файл

@ -1098,15 +1098,15 @@ WebGLContext::AssertCachedBindings()
// Bound object state
if (IsWebGL2()) {
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound);
bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->GLName() : 0;
bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound);
} else {
MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
: 0;
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
}
@ -1119,20 +1119,20 @@ WebGLContext::AssertCachedBindings()
AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);
WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
bound = curTex ? curTex->GLName() : 0;
bound = curTex ? curTex->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound);
curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
bound = curTex ? curTex->GLName() : 0;
bound = curTex ? curTex->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound);
// Buffers
bound = mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0;
bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound);
MOZ_ASSERT(mBoundVertexArray);
WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer;
bound = curBuff ? curBuff->GLName() : 0;
bound = curBuff ? curBuff->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound);
MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors());

Просмотреть файл

@ -266,8 +266,10 @@ WebGLContext::ValidateDataRanges(WebGLintptr readOffset, WebGLintptr writeOffset
MOZ_ASSERT((CheckedInt<WebGLsizeiptr>(writeOffset) + size).isValid());
bool separate = (readOffset + size < writeOffset || writeOffset + size < readOffset);
if (!separate)
ErrorInvalidValue("%s: ranges [readOffset, readOffset + size) and [writeOffset, writeOffset + size) overlap");
if (!separate) {
ErrorInvalidValue("%s: ranges [readOffset, readOffset + size) and [writeOffset, "
"writeOffset + size) overlap", info);
}
return separate;
}

Просмотреть файл

@ -51,7 +51,7 @@ WebGLContext::CreateVertexArray()
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLVertexArray> globj = WebGLVertexArray::Create(this);
nsRefPtr<WebGLVertexArray> globj = CreateVertexArrayImpl();
MakeContextCurrent();
globj->GenVertexArray();
@ -59,6 +59,12 @@ WebGLContext::CreateVertexArray()
return globj.forget();
}
WebGLVertexArray*
WebGLContext::CreateVertexArrayImpl()
{
return WebGLVertexArray::Create(this);
}
void
WebGLContext::DeleteVertexArray(WebGLVertexArray* array)
{
@ -86,9 +92,14 @@ WebGLContext::IsVertexArray(WebGLVertexArray* array)
if (!array)
return false;
return ValidateObjectAllowDeleted("isVertexArray", array) &&
!array->IsDeleted() &&
array->HasEverBeenBound();
if (!ValidateObjectAllowDeleted("isVertexArray", array))
return false;
if (array->IsDeleted())
return false;
MakeContextCurrent();
return array->IsVertexArray();
}
} // namespace mozilla

Просмотреть файл

@ -93,8 +93,8 @@ WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target,
mContext->MakeContextCurrent();
gl::GLContext* gl = mContext->GL();
gl->fBeginQuery(target, query->GLName());
query->BindTo(LOCAL_GL_TIME_ELAPSED_EXT);
gl->fBeginQuery(target, query->mGLName);
query->mTarget = LOCAL_GL_TIME_ELAPSED_EXT;
mActiveQuery = query;
}
@ -137,8 +137,8 @@ WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
}
mContext->MakeContextCurrent();
mContext->GL()->fQueryCounter(query->GLName(), target);
query->BindTo(LOCAL_GL_TIMESTAMP_EXT);
mContext->GL()->fQueryCounter(query->mGLName, target);
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
}
void
@ -210,7 +210,7 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
switch (pname) {
case LOCAL_GL_QUERY_RESULT_EXT: {
GLuint64 result = 0;
mContext->GL()->fGetQueryObjectui64v(query->GLName(),
mContext->GL()->fGetQueryObjectui64v(query->mGLName,
LOCAL_GL_QUERY_RESULT_EXT,
&result);
retval.set(JS::NumberValue(result));
@ -218,7 +218,7 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
}
case LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT: {
GLuint avail = 0;
mContext->GL()->fGetQueryObjectuiv(query->GLName(),
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
&avail);
retval.set(JS::BooleanValue(bool(avail)));

Просмотреть файл

@ -378,7 +378,7 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
const GLenum imageTarget = ImageTarget().get();
const GLint mipLevel = MipLevel();
const GLuint glName = Texture()->GLName();
const GLuint glName = Texture()->mGLName;
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
@ -404,14 +404,18 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
// WebGLFramebuffer
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
: WebGLBindableName<FBTarget>(fbo)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(fbo)
, mStatus(0)
, mReadBufferMode(LOCAL_GL_COLOR_ATTACHMENT0)
, mColorAttachment0(this, LOCAL_GL_COLOR_ATTACHMENT0)
, mDepthAttachment(this, LOCAL_GL_DEPTH_ATTACHMENT)
, mStencilAttachment(this, LOCAL_GL_STENCIL_ATTACHMENT)
, mDepthStencilAttachment(this, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
#ifdef ANDROID
, mIsFB(false)
#endif
{
mContext->mFramebuffers.insertBack(this);
}
@ -432,6 +436,10 @@ WebGLFramebuffer::Delete()
mContext->MakeContextCurrent();
mContext->gl->fDeleteFramebuffers(1, &mGLName);
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
#ifdef ANDROID
mIsFB = false;
#endif
}
void

Просмотреть файл

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -23,12 +22,13 @@ namespace gl {
class WebGLFramebuffer final
: public nsWrapperCache
, public WebGLBindableName<FBTarget>
, public WebGLRefCountedObject<WebGLFramebuffer>
, public LinkedListElement<WebGLFramebuffer>
, public WebGLContextBoundObject
, public SupportsWeakPtr<WebGLFramebuffer>
{
friend class WebGLContext;
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
@ -53,7 +53,6 @@ public:
}
bool IsDefined() const;
bool IsDeleteRequested() const;
TexInternalFormat EffectiveInternalFormat() const;
@ -99,6 +98,8 @@ public:
FBAttachment attachmentLoc) const;
};
const GLuint mGLName;
private:
mutable GLenum mStatus;
@ -111,6 +112,15 @@ private:
AttachPoint mDepthStencilAttachment;
nsTArray<AttachPoint> mMoreColorAttachments;
#ifdef ANDROID
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
// This shows up on Android 2.3 emulator.
//
// So we track the `is a Framebuffer` state ourselves.
bool mIsFB;
#endif
public:
WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);

Просмотреть файл

@ -47,14 +47,16 @@ WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
: WebGLBindable<RBTarget>()
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mPrimaryRB(0)
, mSecondaryRB(0)
, mInternalFormat(0)
, mInternalFormatForGL(0)
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
, mSamples(1)
#ifdef ANDROID
, mIsRB(false)
#endif
{
mContext->MakeContextCurrent();
@ -75,6 +77,9 @@ WebGLRenderbuffer::Delete()
mContext->gl->fDeleteRenderbuffers(1, &mSecondaryRB);
LinkedListElement<WebGLRenderbuffer>::removeFrom(mContext->mRenderbuffers);
#ifdef ANDROID
mIsRB = false;
#endif
}
int64_t

Просмотреть файл

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
@ -16,7 +15,6 @@ namespace mozilla {
class WebGLRenderbuffer final
: public nsWrapperCache
, public WebGLBindable<RBTarget>
, public WebGLRefCountedObject<WebGLRenderbuffer>
, public LinkedListElement<WebGLRenderbuffer>
, public WebGLRectangleObject
@ -41,6 +39,8 @@ public:
GLsizei Samples() const { return mSamples; }
void SetSamples(GLsizei samples) { mSamples = samples; }
GLuint PrimaryGLName() const { return mPrimaryRB; }
GLenum InternalFormat() const { return mInternalFormat; }
void SetInternalFormat(GLenum internalFormat) {
mInternalFormat = internalFormat;
@ -80,7 +80,16 @@ protected:
GLenum mInternalFormatForGL;
WebGLImageDataStatus mImageDataStatus;
GLsizei mSamples;
#ifdef ANDROID
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
// This shows up on Android 2.3 emulator.
//
// So we track the `is a Renderbuffer` state ourselves.
bool mIsRB;
#endif
friend class WebGLContext;
friend class WebGLFramebuffer;
};

Просмотреть файл

@ -12,8 +12,8 @@
namespace mozilla {
WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler)
: WebGLBindableName<GLenum>(sampler),
WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(sampler)
{
mContext->mSamplers.insertBack(this);
}

Просмотреть файл

@ -8,14 +8,12 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLSampler final
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLSampler>
, public LinkedListElement<WebGLSampler>
, public WebGLContextBoundObject
@ -25,6 +23,8 @@ class WebGLSampler final
public:
explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
const GLuint mGLName;
void Delete();
WebGLContext* GetParentObject() const;

Просмотреть файл

@ -92,6 +92,11 @@ TranslateWithoutValidation(const nsACString& sourceNS, bool isWebGL2,
switch (glesslVersion) {
case 100:
if (!versionStrLen) {
/* According to ARB_ES2_compatibility extension glsl
* should accept #version 100 for ES 2 shaders. */
reversionedSource.insert(versionStrStart, "#version 100\n");
}
break;
case 300:
reversionedSource.insert(versionStrStart, "#version 330\n");

Просмотреть файл

@ -24,8 +24,9 @@ WebGLTexture::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {
}
WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
: WebGLBindableName<TexTarget>(tex)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(tex)
, mTarget(LOCAL_GL_NONE)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
, mWrapS(LOCAL_GL_REPEAT)
@ -142,7 +143,7 @@ WebGLTexture::Bind(TexTarget texTarget)
bool firstTimeThisTextureIsBound = !HasEverBeenBound();
if (firstTimeThisTextureIsBound) {
BindTo(texTarget);
mTarget = texTarget.get();
} else if (texTarget != Target()) {
mContext->ErrorInvalidOperation("bindTexture: This texture has already"
" been bound to a different target.");
@ -152,9 +153,7 @@ WebGLTexture::Bind(TexTarget texTarget)
return;
}
GLuint name = GLName();
mContext->gl->fBindTexture(texTarget.get(), name);
mContext->gl->fBindTexture(texTarget.get(), mGLName);
if (firstTimeThisTextureIsBound) {
mFacesCount = (texTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? 6 : 1;
@ -229,7 +228,7 @@ WebGLTexture::SetCustomMipmap()
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
for(size_t face = 0; face < mFacesCount; ++face) {
for (size_t face = 0; face < mFacesCount; ++face) {
ImageInfoAtFace(face, level) = imageInfo;
}
}
@ -276,8 +275,8 @@ WebGLTexture::IsMipmapCubeComplete() const
return false;
for (int i = 0; i < 6; i++) {
const TexImageTarget face = TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP,
i);
const TexImageTarget face =
TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP, i);
if (!DoesMipmapHaveAllLevelsConsistentlyDefined(face))
return false;
}
@ -626,7 +625,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget,
// Try to clear with glClear.
if (imageTarget == LOCAL_GL_TEXTURE_2D) {
bool cleared = ClearWithTempFB(mContext, GLName(), imageTarget, level,
bool cleared = ClearWithTempFB(mContext, mGLName, imageTarget, level,
imageInfo.mEffectiveInternalFormat,
imageInfo.mHeight, imageInfo.mWidth);
if (cleared) {
@ -637,7 +636,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget,
}
// That didn't work. Try uploading zeros then.
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
gl::ScopedBindTexture autoBindTex(mContext->gl, mGLName, mTarget);
size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat);
MOZ_ASSERT((bitspertexel % 8) == 0); // That would only happen for

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/LinkedList.h"
#include "nsAlgorithm.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -31,7 +30,6 @@ IsPOTAssumingNonnegative(GLsizei x)
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
class WebGLTexture final
: public nsWrapperCache
, public WebGLBindableName<TexTarget>
, public WebGLRefCountedObject<WebGLTexture>
, public LinkedListElement<WebGLTexture>
, public WebGLContextBoundObject
@ -42,6 +40,9 @@ public:
void Delete();
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const {
return Context();
}
@ -62,6 +63,12 @@ protected:
// We store information about the various images that are part of this
// texture. (cubemap faces, mipmap levels)
public:
const GLuint mGLName;
protected:
GLenum mTarget;
public:
class ImageInfo
: public WebGLRectangleObject

Просмотреть файл

@ -20,11 +20,17 @@ WebGLTimerQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint aName)
: WebGLBindableName<QueryBinding>(aName)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(aName)
, mTarget(LOCAL_GL_NONE)
{
}
WebGLTimerQuery::~WebGLTimerQuery()
{
DeleteOnce();
}
WebGLTimerQuery*
WebGLTimerQuery::Create(WebGLContext* webgl)
{
@ -41,6 +47,13 @@ WebGLTimerQuery::Delete()
mContext->gl->fDeleteQueries(1, &mGLName);
}
WebGLContext*
WebGLTimerQuery::GetParentObject() const
{
return Context();
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTimerQuery, AddRef)

Просмотреть файл

@ -14,32 +14,32 @@ namespace mozilla {
class WebGLTimerQuery final
: public nsWrapperCache
, public WebGLBindableName<QueryBinding>
, public WebGLRefCountedObject<WebGLTimerQuery>
, public WebGLContextBoundObject
{
public:
static WebGLTimerQuery* Create(WebGLContext* webgl);
// WebGLRefCountedObject
void Delete();
// nsWrapperCache
WebGLContext* GetParentObject() const {
return Context();
}
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const;
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTimerQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
private:
explicit WebGLTimerQuery(WebGLContext* webgl, GLuint aName);
~WebGLTimerQuery() {
DeleteOnce();
}
~WebGLTimerQuery();
GLenum mTarget;
friend class WebGLExtensionDisjointTimerQuery;
};

Просмотреть файл

@ -13,8 +13,8 @@ namespace mozilla {
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl,
GLuint tf)
: WebGLBindableName<GLenum>(tf)
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(tf)
, mMode(LOCAL_GL_NONE)
, mIsActive(false)
, mIsPaused(false)

Просмотреть файл

@ -8,14 +8,12 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLTransformFeedback final
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLTransformFeedback>
, public LinkedListElement<WebGLTransformFeedback>
, public WebGLContextBoundObject
@ -30,11 +28,14 @@ public:
WebGLContext* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
const GLuint mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
private:
~WebGLTransformFeedback();
GLenum mMode;
bool mIsActive;
bool mIsPaused;

Просмотреть файл

@ -21,8 +21,7 @@ WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
: WebGLBindable<VAOBinding>()
, WebGLContextBoundObject(webgl)
: WebGLContextBoundObject(webgl)
, mGLName(0)
{
mContext->mVertexArrays.insertBack(this);
@ -50,6 +49,12 @@ WebGLVertexArray::Delete()
mAttribs.Clear();
}
bool
WebGLVertexArray::IsVertexArray()
{
return IsVertexArrayImpl();
}
void
WebGLVertexArray::EnsureAttrib(GLuint index)
{

Просмотреть файл

@ -8,7 +8,6 @@
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLBuffer.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
@ -20,7 +19,6 @@ class WebGLVertexArrayFake;
class WebGLVertexArray
: public nsWrapperCache
, public WebGLBindable<VAOBinding>
, public WebGLRefCountedObject<WebGLVertexArray>
, public LinkedListElement<WebGLVertexArray>
, public WebGLContextBoundObject
@ -31,14 +29,9 @@ public:
void BindVertexArray() {
// Bind to dummy value to signal that this vertex array has ever been
// bound.
BindTo(LOCAL_GL_VERTEX_ARRAY_BINDING);
BindVertexArrayImpl();
};
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) const {
return index < mAttribs.Length();
@ -49,6 +42,7 @@ public:
// Implement parent classes:
void Delete();
bool IsVertexArray();
WebGLContext* GetParentObject() const {
return Context();
@ -68,6 +62,11 @@ protected:
MOZ_ASSERT(IsDeleted());
}
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
virtual bool IsVertexArrayImpl() = 0;
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;

Просмотреть файл

@ -10,6 +10,11 @@
namespace mozilla {
WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
, mIsVAO(false)
{ }
void
WebGLVertexArrayFake::BindVertexArrayImpl()
{
@ -52,6 +57,19 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
mIsVAO = true;
}
void
WebGLVertexArrayFake::DeleteImpl()
{
mIsVAO = false;
}
bool
WebGLVertexArrayFake::IsVertexArrayImpl()
{
return mIsVAO;
}
} // namespace mozilla

Просмотреть файл

@ -13,21 +13,22 @@ namespace mozilla {
class WebGLVertexArrayFake final
: public WebGLVertexArray
{
public:
friend class WebGLVertexArray;
protected:
virtual void BindVertexArrayImpl() override;
virtual void DeleteImpl() override {};
virtual void DeleteImpl() override;
virtual void GenVertexArray() override {};
virtual bool IsVertexArrayImpl() override;
private:
explicit WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
explicit WebGLVertexArrayFake(WebGLContext* webgl);
~WebGLVertexArrayFake() {
DeleteOnce();
}
friend class WebGLVertexArray;
bool mIsVAO;
};
} // namespace mozilla

Просмотреть файл

@ -10,6 +10,18 @@
namespace mozilla {
WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
#if defined(XP_LINUX)
, mIsVAO(false)
#endif
{ }
WebGLVertexArrayGL::~WebGLVertexArrayGL()
{
DeleteOnce();
}
void
WebGLVertexArrayGL::DeleteImpl()
{
@ -17,14 +29,21 @@ WebGLVertexArrayGL::DeleteImpl()
mContext->MakeContextCurrent();
mContext->gl->fDeleteVertexArrays(1, &mGLName);
#if defined(XP_LINUX)
mIsVAO = false;
#endif
}
void
WebGLVertexArrayGL::BindVertexArrayImpl()
{
mContext->mBoundVertexArray = this;
mContext->gl->fBindVertexArray(mGLName);
#if defined(XP_LINUX)
mIsVAO = true;
#endif
}
void
@ -33,4 +52,21 @@ WebGLVertexArrayGL::GenVertexArray()
mContext->gl->fGenVertexArrays(1, &mGLName);
}
bool
WebGLVertexArrayGL::IsVertexArrayImpl()
{
#if defined(XP_LINUX)
gl::GLContext* gl = mContext->gl;
if (gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLVendor::VMware &&
gl->Renderer() == gl::GLRenderer::GalliumLlvmpipe)
{
return mIsVAO;
}
#endif
mContext->MakeContextCurrent();
return mContext->gl->fIsVertexArray(mGLName) != 0;
}
} // namespace mozilla

Просмотреть файл

@ -10,24 +10,28 @@
namespace mozilla {
class WebGLVertexArrayGL final
class WebGLVertexArrayGL
: public WebGLVertexArray
{
friend class WebGLVertexArray;
public:
virtual void DeleteImpl() override;
virtual void BindVertexArrayImpl() override;
virtual void GenVertexArray() override;
virtual bool IsVertexArrayImpl() override;
private:
explicit WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
protected:
explicit WebGLVertexArrayGL(WebGLContext* webgl);
~WebGLVertexArrayGL();
~WebGLVertexArrayGL() {
DeleteOnce();
}
friend class WebGLVertexArray;
#if defined(XP_LINUX)
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
//
// So we track the `is a VAO` state ourselves.
bool mIsVAO;
#endif
};
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLVertexArrayObject.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
namespace mozilla {
namespace dom {
WebGLVertexArray*
WebGLVertexArrayObject::Create(WebGLContext* webgl)
{
// WebGL 2: This is core in GL ES 3. If support is missing something
// is very wrong.
bool vaoSupport = webgl->GL()->IsSupported(gl::GLFeature::vertex_array_object);
MOZ_RELEASE_ASSERT(vaoSupport, "Vertex Array Objects aren't supported.");
if (vaoSupport)
return new WebGLVertexArrayObject(webgl);
return nullptr;
}
JSObject*
WebGLVertexArrayObject::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto)
{
return dom::WebGLVertexArrayObjectBinding::Wrap(cx, this, givenProto);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_WebGLVertexArrayObject_h
#define mozilla_dom_WebGLVertexArrayObject_h
#include "WebGLVertexArrayGL.h"
namespace mozilla {
namespace dom {
/**
* This class implements the DOM bindings for WebGL 2 VAO.
*
* This exists to so the object returned from gl.createVertexArray()
* is an instance of WebGLVertexArrayObject (to match the WebGL 2
* spec.)
*/
class WebGLVertexArrayObject final
: public WebGLVertexArrayGL
{
public:
static WebGLVertexArray* Create(WebGLContext* webgl);
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
private:
explicit WebGLVertexArrayObject(WebGLContext* webgl)
: WebGLVertexArrayGL(webgl)
{ }
~WebGLVertexArrayObject() {
DeleteOnce();
}
};
} // namespace dom
} // namespace mozilla
#endif // !mozilla_dom_WebGLVertexArrayObject_h

Просмотреть файл

@ -31,6 +31,7 @@ EXPORTS.mozilla.dom += [
'CanvasUtils.h',
'ImageData.h',
'TextMetrics.h',
'WebGLVertexArrayObject.h',
]
# http://support.microsoft.com/kb/143208
@ -128,6 +129,7 @@ UNIFIED_SOURCES += [
'WebGLVertexArray.cpp',
'WebGLVertexArrayFake.cpp',
'WebGLVertexArrayGL.cpp',
'WebGLVertexArrayObject.cpp',
]
LOCAL_INCLUDES += [
'/js/xpconnect/wrappers',

Просмотреть файл

@ -548,14 +548,16 @@ FetchDriver::ContinueHttpFetchAfterNetworkFetch()
}
already_AddRefed<InternalResponse>
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI)
{
MOZ_ASSERT(aResponse);
if (!aResponse->FinalURL()) {
nsAutoCString reqURL;
nsAutoCString reqURL;
if (aFinalURI) {
aFinalURI->GetSpec(reqURL);
} else {
mRequest->GetURL(reqURL);
aResponse->SetUrl(reqURL);
}
aResponse->SetUrl(reqURL);
// FIXME(nsm): Handle mixed content check, step 7 of fetch.
@ -584,7 +586,7 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
void
FetchDriver::BeginResponse(InternalResponse* aResponse)
{
nsRefPtr<InternalResponse> r = BeginAndGetFilteredResponse(aResponse);
nsRefPtr<InternalResponse> r = BeginAndGetFilteredResponse(aResponse, nullptr);
// Release the ref.
}
@ -716,9 +718,17 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
response->InitChannelInfo(channel);
nsCOMPtr<nsIURI> channelURI;
rv = channel->GetURI(getter_AddRefs(channelURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
FailWithNetworkError();
// Cancel request.
return rv;
}
// Resolves fetch() promise which may trigger code running in a worker. Make
// sure the Response is fully initialized before calling this.
mResponse = BeginAndGetFilteredResponse(response);
mResponse = BeginAndGetFilteredResponse(response, channelURI);
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {

Просмотреть файл

@ -88,8 +88,9 @@ private:
nsresult HttpFetch(bool aCORSFlag = false, bool aCORSPreflightFlag = false, bool aAuthenticationFlag = false);
nsresult ContinueHttpFetchAfterNetworkFetch();
// Returns the filtered response sent to the observer.
// Callers who don't have access to a channel can pass null for aFinalURI.
already_AddRefed<InternalResponse>
BeginAndGetFilteredResponse(InternalResponse* aResponse);
BeginAndGetFilteredResponse(InternalResponse* aResponse, nsIURI* aFinalURI);
// Utility since not all cases need to do any post processing of the filtered
// response.
void BeginResponse(InternalResponse* aResponse);

Просмотреть файл

@ -14,7 +14,6 @@ namespace dom {
InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
: mType(ResponseType::Default)
, mFinalURL(false)
, mStatus(aStatus)
, mStatusText(aStatusText)
, mHeaders(new InternalHeaders(HeadersGuardEnum::Response))

Просмотреть файл

@ -48,7 +48,6 @@ public:
response->mType = ResponseType::Opaque;
response->mTerminationReason = mTerminationReason;
response->mURL = mURL;
response->mFinalURL = mFinalURL;
response->mChannelInfo = mChannelInfo;
response->mWrappedResponse = this;
return response.forget();
@ -90,18 +89,6 @@ public:
mURL.Assign(aURL);
}
bool
FinalURL() const
{
return mFinalURL;
}
void
SetFinalURL(bool aFinalURL)
{
mFinalURL = aFinalURL;
}
uint16_t
GetStatus() const
{
@ -197,7 +184,6 @@ private:
copy->mType = mType;
copy->mTerminationReason = mTerminationReason;
copy->mURL = mURL;
copy->mFinalURL = mFinalURL;
copy->mChannelInfo = mChannelInfo;
return copy.forget();
}
@ -205,7 +191,6 @@ private:
ResponseType mType;
nsCString mTerminationReason;
nsCString mURL;
bool mFinalURL;
const uint16_t mStatus;
const nsCString mStatusText;
nsRefPtr<InternalHeaders> mHeaders;

Просмотреть файл

@ -858,7 +858,8 @@ ReadCompressedIndexDataValuesFromBlob(
blobDataIter += keyBufferLength;
if (NS_WARN_IF(!aIndexValues.InsertElementSorted(
IndexDataValue(indexId, unique, Key(keyBuffer))))) {
IndexDataValue(indexId, unique, Key(keyBuffer)),
fallible))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_OUT_OF_MEMORY;
}
@ -2734,7 +2735,8 @@ InsertIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
}
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(indexId, !!unique, value)));
indexValues.InsertElementSorted(IndexDataValue(indexId, !!unique, value),
fallible));
// Compress the array.
UniqueFreePtr<uint8_t> indexValuesBlob;
@ -17856,7 +17858,8 @@ DatabaseOperationBase::IndexDataValuesFromUpdateInfos(
MOZ_ALWAYS_TRUE(aUniqueIndexTable.Get(indexId, &unique));
MOZ_ALWAYS_TRUE(
aIndexValues.InsertElementSorted(IndexDataValue(indexId, unique, key)));
aIndexValues.InsertElementSorted(IndexDataValue(indexId, unique, key),
fallible));
}
return NS_OK;
@ -22291,7 +22294,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
metadata.unique(),
info.value())));
info.value()),
fallible));
}
UniqueFreePtr<uint8_t> indexValuesBlob;
@ -22327,7 +22331,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
MOZ_ALWAYS_TRUE(
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
metadata.unique(),
info.value())));
info.value()),
fallible));
}
}

Просмотреть файл

@ -133,4 +133,16 @@ AbstractThread::InitStatics()
sCurrentThreadTLS.set(sMainThread);
}
void
AbstractThread::DispatchStateChange(already_AddRefed<nsIRunnable> aRunnable)
{
GetCurrent()->TailDispatcher().AddStateChangeTask(this, Move(aRunnable));
}
/* static */ void
AbstractThread::DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable)
{
GetCurrent()->TailDispatcher().AddDirectTask(Move(aRunnable));
}
} // namespace mozilla

Просмотреть файл

@ -79,6 +79,10 @@ public:
// Must be called exactly once during startup.
static void InitStatics();
void DispatchStateChange(already_AddRefed<nsIRunnable> aRunnable);
static void DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable);
protected:
virtual ~AbstractThread() {}
static ThreadLocal<AbstractThread*> sCurrentThreadTLS;

Просмотреть файл

@ -165,18 +165,10 @@ AudioSink::SetPreservesPitch(bool aPreservesPitch)
}
void
AudioSink::StartPlayback()
AudioSink::SetPlaying(bool aPlaying)
{
AssertCurrentThreadInMonitor();
mPlaying = true;
GetReentrantMonitor().NotifyAll();
}
void
AudioSink::StopPlayback()
{
AssertCurrentThreadInMonitor();
mPlaying = false;
mPlaying = aPlaying;
GetReentrantMonitor().NotifyAll();
}

Просмотреть файл

@ -42,8 +42,7 @@ public:
void SetPlaybackRate(double aPlaybackRate);
void SetPreservesPitch(bool aPreservesPitch);
void StartPlayback();
void StopPlayback();
void SetPlaying(bool aPlaying);
private:
~AudioSink() {}

Просмотреть файл

@ -69,6 +69,19 @@ private:
bool mStreamFinishedOnMainThread;
};
static void
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
{
int32_t delta = aBlocking ? 1 : -1;
if (NS_IsMainThread()) {
aStream->ChangeExplicitBlockerCount(delta);
} else {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
AbstractThread::MainThread()->Dispatch(r.forget());
}
}
DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
: mAudioFramesWritten(0)
, mNextVideoTime(-1)
@ -78,14 +91,13 @@ DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
, mHaveSentFinishAudio(false)
, mHaveSentFinishVideo(false)
, mStream(aStream)
, mHaveBlockedForPlayState(false)
, mHaveBlockedForStateMachineNotPlaying(false)
, mPlaying(false)
, mEOSVideoCompensation(false)
{
mListener = new DecodedStreamGraphListener(mStream);
mStream->AddListener(mListener);
// Block the stream until the initialization is done.
mStream->ChangeExplicitBlockerCount(1);
// Block the stream as mPlaying is initially false.
UpdateStreamBlocking(mStream, true);
}
DecodedStreamData::~DecodedStreamData()
@ -106,6 +118,15 @@ DecodedStreamData::GetPosition() const
return mListener->GetLastOutputTime();
}
void
DecodedStreamData::SetPlaying(bool aPlaying)
{
if (mPlaying != aPlaying) {
mPlaying = aPlaying;
UpdateStreamBlocking(mStream, !mPlaying);
}
}
class OutputStreamListener : public MediaStreamListener {
typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
public:
@ -290,4 +311,12 @@ DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
}
}
void
DecodedStream::SetPlaying(bool aPlaying)
{
GetReentrantMonitor().AssertCurrentThreadIn();
MOZ_ASSERT(mData);
mData->SetPlaying(aPlaying);
}
} // namespace mozilla

Просмотреть файл

@ -41,6 +41,7 @@ public:
~DecodedStreamData();
bool IsFinished() const;
int64_t GetPosition() const;
void SetPlaying(bool aPlaying);
/* The following group of fields are protected by the decoder's monitor
* and can be read or written on any thread.
@ -66,12 +67,7 @@ public:
// The decoder is responsible for calling Destroy() on this stream.
const nsRefPtr<SourceMediaStream> mStream;
nsRefPtr<DecodedStreamGraphListener> mListener;
// True when we've explicitly blocked this stream because we're
// not in PLAY_STATE_PLAYING. Used on the main thread only.
bool mHaveBlockedForPlayState;
// We also have an explicit blocker on the stream when
// mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
bool mHaveBlockedForStateMachineNotPlaying;
bool mPlaying;
// True if we need to send a compensation video frame to ensure the
// StreamTime going forward.
bool mEOSVideoCompensation;
@ -96,6 +92,7 @@ public:
nsTArray<OutputStreamData>& OutputStreams();
ReentrantMonitor& GetReentrantMonitor() const;
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
void SetPlaying(bool aPlaying);
private:
void Connect(OutputStreamData* aStream);

Просмотреть файл

@ -639,7 +639,8 @@ MediaRawDataWriter::Prepend(const uint8_t* aData, size_t aSize)
}
// We ensure sufficient capacity above so this shouldn't fail.
MOZ_ALWAYS_TRUE(mBuffer->InsertElementsAt(mTarget->mPadding, aData, aSize));
MOZ_ALWAYS_TRUE(mBuffer->InsertElementsAt(mTarget->mPadding, aData, aSize,
fallible));
mTarget->mSize += aSize;
mSize = mTarget->mSize;
return true;

Просмотреть файл

@ -272,6 +272,14 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
// timeEndPeriod() call.
timeBeginPeriod(1);
#endif
AudioQueue().AddPopListener(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioPopped),
mTaskQueue);
VideoQueue().AddPopListener(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnVideoPopped),
mTaskQueue);
}
MediaDecoderStateMachine::~MediaDecoderStateMachine()
@ -314,8 +322,6 @@ MediaDecoderStateMachine::InitializationTask()
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
}
bool MediaDecoderStateMachine::HasFutureAudio()
@ -430,19 +436,6 @@ static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
return lastVideoStratTime == aInput.GetDuration();
}
static void
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
{
int32_t delta = aBlocking ? 1 : -1;
if (NS_IsMainThread()) {
aStream->ChangeExplicitBlockerCount(delta);
} else {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
AbstractThread::MainThread()->Dispatch(r.forget());
}
}
void MediaDecoderStateMachine::SendStreamData()
{
MOZ_ASSERT(OnTaskQueue());
@ -481,12 +474,6 @@ void MediaDecoderStateMachine::SendStreamData()
}
mediaStream->FinishAddTracks();
stream->mStreamInitialized = true;
// Make sure stream blocking is updated before sending stream data so we
// don't 'leak' data when the stream is supposed to be blocked.
UpdateStreamBlockingForPlayState();
UpdateStreamBlockingForStateMachinePlaying();
UpdateStreamBlocking(mediaStream, false);
}
if (mInfo.HasAudio()) {
@ -513,6 +500,12 @@ void MediaDecoderStateMachine::SendStreamData()
endPosition = std::max(endPosition,
mediaStream->TicksToTimeRoundDown(mInfo.mAudio.mRate,
stream->mAudioFramesWritten));
CheckedInt64 playedUsecs = mStreamStartTime +
FramesToUsecs(stream->mAudioFramesWritten, mInfo.mAudio.mRate);
if (playedUsecs.isValid()) {
OnAudioEndTimeUpdate(playedUsecs.value());
}
}
if (mInfo.HasVideo()) {
@ -601,8 +594,7 @@ void MediaDecoderStateMachine::SendStreamData()
// Therefore we only discard those behind the stream clock to throttle
// the decoding speed.
if (a && a->mTime <= clockTime) {
OnAudioEndTimeUpdate(std::max(mAudioEndTime, a->GetEndTime()));
nsRefPtr<AudioData> releaseMe = PopAudio();
nsRefPtr<AudioData> releaseMe = AudioQueue().PopFront();
continue;
}
break;
@ -926,22 +918,25 @@ MediaDecoderStateMachine::PushFront(VideoData* aSample)
UpdateNextFrameStatus();
}
already_AddRefed<AudioData>
MediaDecoderStateMachine::PopAudio()
void
MediaDecoderStateMachine::OnAudioPopped()
{
MOZ_ASSERT(OnTaskQueue());
nsRefPtr<AudioData> sample = AudioQueue().PopFront();
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
UpdateNextFrameStatus();
return sample.forget();
DispatchAudioDecodeTaskIfNeeded();
}
already_AddRefed<VideoData>
MediaDecoderStateMachine::PopVideo()
void
MediaDecoderStateMachine::OnVideoPopped()
{
MOZ_ASSERT(OnTaskQueue());
nsRefPtr<VideoData> sample = VideoQueue().PopFront();
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
UpdateNextFrameStatus();
return sample.forget();
DispatchVideoDecodeTaskIfNeeded();
// Notify the decode thread that the video queue's buffers may have
// free'd up space for more frames.
mDecoder->GetReentrantMonitor().NotifyAll();
}
void
@ -1295,7 +1290,6 @@ void MediaDecoderStateMachine::StopPlayback()
// so it can pause audio playback.
mDecoder->GetReentrantMonitor().NotifyAll();
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
UpdateStreamBlockingForStateMachinePlaying();
DispatchDecodeTasksIfNeeded();
}
@ -1333,7 +1327,6 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
NS_ENSURE_SUCCESS_VOID(rv);
mDecoder->GetReentrantMonitor().NotifyAll();
UpdateStreamBlockingForStateMachinePlaying();
DispatchDecodeTasksIfNeeded();
}
@ -2306,17 +2299,6 @@ MediaDecoderStateMachine::DecodeFirstFrame()
MOZ_ASSERT(mState == DECODER_STATE_DECODING_FIRSTFRAME);
DECODER_LOG("DecodeFirstFrame started");
if (HasAudio()) {
RefPtr<nsIRunnable> decodeTask(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DispatchAudioDecodeTaskIfNeeded));
AudioQueue().AddPopListener(decodeTask, TaskQueue());
}
if (HasVideo()) {
RefPtr<nsIRunnable> decodeTask(
NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded));
VideoQueue().AddPopListener(decodeTask, TaskQueue());
}
if (IsRealTime()) {
SetStartTime(0);
nsresult res = FinishDecodeFirstFrame();
@ -2948,10 +2930,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
currentFrame->mTime, clock_time, ++droppedFrames);
}
currentFrame = frame;
nsRefPtr<VideoData> releaseMe = PopVideo();
// Notify the decode thread that the video queue's buffers may have
// free'd up space for more frames.
mDecoder->GetReentrantMonitor().NotifyAll();
nsRefPtr<VideoData> releaseMe = VideoQueue().PopFront();
OnPlaybackOffsetUpdate(frame->mOffset);
if (VideoQueue().GetSize() == 0)
break;
@ -3296,13 +3275,11 @@ void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
{
AssertCurrentThreadInMonitor();
mPlayStartTime = aTimeStamp;
if (!mAudioSink) {
return;
}
if (!mPlayStartTime.IsNull()) {
mAudioSink->StartPlayback();
} else {
mAudioSink->StopPlayback();
if (mAudioSink) {
mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
} else if (mAudioCaptured) {
mDecodedStream.SetPlaying(!mPlayStartTime.IsNull());
}
}
@ -3505,6 +3482,9 @@ void MediaDecoderStateMachine::DispatchAudioCaptured()
// the 1st frame. But this is OK since we will update mStreamStartTime
// again in SetStartTime().
self->mStreamStartTime = self->GetMediaTime();
// Reset mAudioEndTime which will be updated as we send audio data to
// stream. Otherwise it will remain -1 if we don't have audio.
self->mAudioEndTime = -1;
self->mAudioCaptured = true;
self->ScheduleStateMachine();
}
@ -3526,44 +3506,12 @@ void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
DispatchAudioCaptured();
}
void MediaDecoderStateMachine::UpdateStreamBlockingForPlayState()
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
auto stream = GetDecodedStream();
if (!stream) {
return;
}
bool blocking = mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
mLogicallySeeking;
if (blocking != stream->mHaveBlockedForPlayState) {
stream->mHaveBlockedForPlayState = blocking;
UpdateStreamBlocking(stream->mStream, blocking);
}
}
void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
{
AssertCurrentThreadInMonitor();
auto stream = GetDecodedStream();
if (!stream) {
return;
}
bool blocking = !IsPlaying();
if (blocking != stream->mHaveBlockedForStateMachineNotPlaying) {
stream->mHaveBlockedForStateMachineNotPlaying = blocking;
UpdateStreamBlocking(stream->mStream, blocking);
}
}
void MediaDecoderStateMachine::RecreateDecodedStream(MediaStreamGraph* aGraph)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecodedStream.RecreateData(aGraph);
mDecodedStream.SetPlaying(IsPlaying());
}
} // namespace mozilla

Просмотреть файл

@ -162,13 +162,6 @@ private:
void DispatchAudioCaptured();
// Update blocking state of mDecodedStream when mPlayState or
// mLogicallySeeking change. Decoder monitor must be held.
void UpdateStreamBlockingForPlayState();
// Call this IsPlaying() changes. Decoder monitor must be held.
void UpdateStreamBlockingForStateMachinePlaying();
// Recreates mDecodedStream. Call this to create mDecodedStream at first,
// and when seeking, to ensure a new stream is set up with fresh buffers.
// Decoder monitor must be held.
@ -427,12 +420,8 @@ protected:
void PushFront(AudioData* aSample);
void PushFront(VideoData* aSample);
// Pops MediaData* samples from their respective MediaQueues.
// Note that the audio queue is also drained on the audio thread,
// which we can't easily react to - This should be fixed when we
// remove the audio thread in bug 750596.
already_AddRefed<AudioData> PopAudio();
already_AddRefed<VideoData> PopVideo();
void OnAudioPopped();
void OnVideoPopped();
void VolumeChanged();
void LogicalPlaybackRateChanged();

Просмотреть файл

@ -197,7 +197,7 @@ private:
// updates at all if the value ends up where it started.
if (!alreadyNotifying) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(this, &Impl::DoNotify);
AbstractThread::GetCurrent()->TailDispatcher().AddDirectTask(r.forget());
AbstractThread::DispatchDirectTask(r.forget());
}
}
@ -222,7 +222,7 @@ private:
}
for (size_t i = 0; i < mMirrors.Length(); ++i) {
OwnerThread()->TailDispatcher().AddStateChangeTask(mMirrors[i]->OwnerThread(), MakeNotifier(mMirrors[i]));
mMirrors[i]->OwnerThread()->DispatchStateChange(MakeNotifier(mMirrors[i]));
}
}

Просмотреть файл

@ -60,6 +60,10 @@ TrialCreatePrefName(const nsAString& aKeySystem)
GMPVideoDecoderTrialCreator::TrialCreateState
GMPVideoDecoderTrialCreator::GetCreateTrialState(const nsAString& aKeySystem)
{
if (Preferences::GetBool("media.gmp.always-trial-create", false)) {
return Pending;
}
const char* pref = TrialCreatePrefName(aKeySystem);
if (!pref) {
return Pending;

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "gmp-entrypoints.h"
#include "prlink.h"
#include "prenv.h"
#include <string>
@ -168,22 +169,25 @@ GMPLoaderImpl::Load(const char* aLibPath,
if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
return false;
}
// We've successfully bound the origin salt to node id.
// rlz_lib::GetRawMachineId and/or the system functions it
// called could have left user identifiable data on the stack,
// so carefully zero the stack down to the guard page.
uint8_t* top;
uint8_t* bottom;
if (!GetStackAfterCurrentFrame(&top, &bottom)) {
return false;
}
assert(top >= bottom);
// Inline instructions equivalent to RtlSecureZeroMemory().
// We can't just use RtlSecureZeroMemory here directly, as in debug
// builds, RtlSecureZeroMemory() can't be inlined, and the stack
// memory it uses would get wiped by itself running, causing crashes.
for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
*p = 0;
if (!PR_GetEnv("MOZ_GMP_DISABLE_NODE_ID_CLEANUP")) {
// We've successfully bound the origin salt to node id.
// rlz_lib::GetRawMachineId and/or the system functions it
// called could have left user identifiable data on the stack,
// so carefully zero the stack down to the guard page.
uint8_t* top;
uint8_t* bottom;
if (!GetStackAfterCurrentFrame(&top, &bottom)) {
return false;
}
assert(top >= bottom);
// Inline instructions equivalent to RtlSecureZeroMemory().
// We can't just use RtlSecureZeroMemory here directly, as in debug
// builds, RtlSecureZeroMemory() can't be inlined, and the stack
// memory it uses would get wiped by itself running, causing crashes.
for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
*p = 0;
}
}
} else
#endif

Просмотреть файл

@ -237,7 +237,8 @@ TCPSocketChild::SendSend(JS::Handle<JS::Value> aData,
if (!data) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes)) {
if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes,
fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}

Просмотреть файл

@ -311,7 +311,7 @@ TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle<JS::Value> aDataVa
errLine = __LINE__;
break;
}
if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) {
if (!fallibleArr.InsertElementsAt(0, buffer, nbytes, fallible)) {
errLine = __LINE__;
break;
}

Просмотреть файл

@ -249,7 +249,7 @@ UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr,
NS_ENSURE_ARG(aData);
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -451,7 +451,7 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage
}
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
if (!fallibleArray.InsertElementsAt(0, buffer, len, fallible)) {
FireInternalError(__LINE__);
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -5098,7 +5098,9 @@ OriginParser::HandleToken(const nsDependentCSubstring& aToken)
return;
}
mState = eExpectingDriveLetterOrPathnameComponent;
mState =
mTokenizer.hasMoreTokens() ? eExpectingDriveLetterOrPathnameComponent
: eComplete;
return;
}
@ -5216,7 +5218,7 @@ OriginParser::HandleToken(const nsDependentCSubstring& aToken)
void
OriginParser::HandleTrailingSeparator()
{
MOZ_ASSERT(mState = eComplete);
MOZ_ASSERT(mState == eComplete);
MOZ_ASSERT(mSchemaType == eFile);
mPathnameComponents.AppendElement(EmptyCString());

Просмотреть файл

@ -385,7 +385,8 @@ DOMSVGPathSegList::InsertItemBefore(DOMSVGPathSeg& aNewItem,
MOZ_ALWAYS_TRUE(InternalList().mData.InsertElementsAt(internalIndex,
segAsRaw,
1 + argCount));
1 + argCount,
fallible));
MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex,
ItemProxy(domItem.get(),
internalIndex),

Просмотреть файл

@ -27,12 +27,10 @@ skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = buildapp == 'b2g' # Bug 1137683
[test_fetch_basic_http.html]
[test_fetch_basic_http_sw_reroute.html]
skip-if = true # Bug 1170937, need fully support for redirects
#skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g
[test_fetch_cors.html]
[test_fetch_cors_sw_reroute.html]
skip-if = true # Bug 1170937, need fully support for redirects
#skip-if = buildapp == 'b2g' # Bug 1137683
skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g
[test_formdataparsing.html]
[test_formdataparsing_sw_reroute.html]
skip-if = buildapp == 'b2g' # Bug 1137683

Просмотреть файл

@ -26,11 +26,9 @@ interface WebGLSync {
interface WebGLTransformFeedback {
};
/*
[Pref="webgl.enable-prototype-webgl2"]
interface WebGLVertexArrayObject {
};
*/
[Pref="webgl.enable-prototype-webgl2"]
interface WebGL2RenderingContext : WebGLRenderingContext
@ -238,7 +236,6 @@ interface WebGL2RenderingContext : WebGLRenderingContext
const GLenum RGB8_SNORM = 0x8F96;
const GLenum RGBA8_SNORM = 0x8F97;
const GLenum SIGNED_NORMALIZED = 0x8F9C;
const GLenum PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69;
const GLenum COPY_READ_BUFFER = 0x8F36;
const GLenum COPY_WRITE_BUFFER = 0x8F37;
const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; /* Same as COPY_READ_BUFFER */
@ -291,10 +288,6 @@ interface WebGL2RenderingContext : WebGLRenderingContext
const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A;
const GLenum SAMPLER_BINDING = 0x8919;
const GLenum RGB10_A2UI = 0x906F;
const GLenum TEXTURE_SWIZZLE_R = 0x8E42;
const GLenum TEXTURE_SWIZZLE_G = 0x8E43;
const GLenum TEXTURE_SWIZZLE_B = 0x8E44;
const GLenum TEXTURE_SWIZZLE_A = 0x8E45;
const GLenum GREEN = 0x1904;
const GLenum BLUE = 0x1905;
const GLenum INT_2_10_10_10_REV = 0x8D9F;
@ -475,10 +468,8 @@ interface WebGL2RenderingContext : WebGLRenderingContext
void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
/* Vertex Array Objects */
/*
WebGLVertexArrayObject? createVertexArray();
void deleteVertexArray(WebGLVertexArrayObject? vertexArray);
[WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray);
void bindVertexArray(WebGLVertexArrayObject? array);
*/
};

Просмотреть файл

@ -983,9 +983,11 @@ private:
// If the load principal is the system principal then the channel
// principal must also be the system principal (we do not allow chrome
// code to create workers with non-chrome scripts). Otherwise this channel
// principal must be same origin with the load principal (we check again
// here in case redirects changed the location of the script).
// code to create workers with non-chrome scripts, and if we ever decide
// to change this we need to make sure we don't always set
// mPrincipalIsSystem to true in WorkerPrivate::GetLoadInfo()). Otherwise
// this channel principal must be same origin with the load principal (we
// check again here in case redirects changed the location of the script).
if (nsContentUtils::IsSystemPrincipal(loadPrincipal)) {
if (!nsContentUtils::IsSystemPrincipal(channelPrincipal)) {
// See if this is a resource URI. Since JSMs usually come from

Просмотреть файл

@ -4885,12 +4885,15 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
return NS_ERROR_DOM_SECURITY_ERR;
}
// Chrome callers (whether ChromeWorker of Worker) always get the system
// principal here as they're allowed to load anything. The script loader may
// change the principal later depending on the script uri.
// Chrome callers (whether creating a ChromeWorker or Worker) always get the
// system principal here as they're allowed to load anything. The script
// loader will refuse to run any script that does not also have the system
// principal.
if (isChrome) {
rv = ssm->GetSystemPrincipal(getter_AddRefs(loadInfo.mPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
loadInfo.mPrincipalIsSystem = true;
}
// See if we're being called from a window.

Просмотреть файл

@ -1964,7 +1964,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = aTexture->QueryInterface((IDXGISurface**)byRef(surface));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to QI texture to surface. Code: " << hr;
gfxCriticalError() << "Failed to QI texture to surface. Code: " << hexa(hr);
return nullptr;
}
@ -1982,7 +1982,8 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
hr = factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to create D2D render target for texture. Code:" << hr << " " << mSize << " Format: " << uint32_t(aFormat);
gfxCriticalError() << "Failed to create D2D render target for texture. Code: "
<< hexa(hr) << " " << mSize << " Format: " << uint32_t(aFormat);
return nullptr;
}

Просмотреть файл

@ -413,7 +413,8 @@ CompositorD3D11::GetTextureFactoryIdentifier()
if (mAttachments->mSyncTexture) {
HRESULT hr = mAttachments->mSyncTexture->GetSharedHandle(&ident.mSyncHandle);
if (FAILED(hr) || !ident.mSyncHandle) {
gfxCriticalError() << "Failed to get SharedHandle for sync texture. Result: " << hr;
gfxCriticalError() << "Failed to get SharedHandle for sync texture. Result: "
<< hexa(hr);
MOZ_CRASH();
}
}
@ -1342,7 +1343,7 @@ CompositorD3D11::UpdateConstantBuffers()
hr = mContext->Map(mAttachments->mVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
if (Failed(hr) || !resource.pData) {
gfxCriticalError() << "Failed to map VSConstantBuffer. Result: " << hr;
gfxCriticalError() << "Failed to map VSConstantBuffer. Result: " << hexa(hr);
return false;
}
*(VertexShaderConstants*)resource.pData = mVSConstants;
@ -1351,7 +1352,7 @@ CompositorD3D11::UpdateConstantBuffers()
hr = mContext->Map(mAttachments->mPSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
if (Failed(hr) || !resource.pData) {
gfxCriticalError() << "Failed to map PSConstantBuffer. Result: " << hr;
gfxCriticalError() << "Failed to map PSConstantBuffer. Result: " << hexa(hr);
return false;
}
*(PixelShaderConstants*)resource.pData = mPSConstants;

Просмотреть файл

@ -910,7 +910,10 @@ gfxFontconfigFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
#endif
gfxFcPlatformFontList::gfxFcPlatformFontList()
: mLocalNames(64), mGenericMappings(32), mLastConfig(nullptr)
: mLocalNames(64)
, mGenericMappings(32)
, mFcSubstituteCache(64)
, mLastConfig(nullptr)
{
// if the rescan interval is set, start the timer
int rescanInterval = FcConfigGetRescanInterval(nullptr);
@ -1036,6 +1039,8 @@ gfxFcPlatformFontList::InitFontList()
mLocalNames.Clear();
mGenericMappings.Clear();
mFcSubstituteCache.Clear();
sSentinelFirstFamily = nullptr;
// iterate over available fonts
FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem);
@ -1048,7 +1053,6 @@ gfxFcPlatformFontList::InitFontList()
#endif
mOtherFamilyNamesInitialized = true;
sSentinelFirstFamily = nullptr;
return NS_OK;
}
@ -1240,6 +1244,14 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
// In this case fontconfig is including Tex Gyre Heros and
// Nimbus Sans L as alternatives for Helvetica.
// Because the FcConfigSubstitute call is quite expensive, we cache the
// actual font family found via this process. So check the cache first:
NS_ConvertUTF16toUTF8 familyToFind(familyName);
gfxFontFamily* cached = mFcSubstituteCache.GetWeak(familyToFind);
if (cached) {
return cached;
}
const FcChar8* kSentinelName = ToFcChar8Ptr("-moz-sentinel");
if (!sSentinelFirstFamily) {
nsAutoRef<FcPattern> sentinelSubst(FcPatternCreate());
@ -1250,7 +1262,6 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
// substitutions for font, -moz-sentinel pattern
nsAutoRef<FcPattern> fontWithSentinel(FcPatternCreate());
NS_ConvertUTF16toUTF8 familyToFind(familyName);
FcPatternAddString(fontWithSentinel, FC_FAMILY, ToFcChar8Ptr(familyToFind.get()));
FcPatternAddString(fontWithSentinel, FC_FAMILY, kSentinelName);
FcConfigSubstitute(nullptr, fontWithSentinel, FcMatchPattern);
@ -1269,6 +1280,9 @@ gfxFcPlatformFontList::FindFamily(const nsAString& aFamily,
}
gfxFontFamily* foundFamily = gfxPlatformFontList::FindFamily(subst);
if (foundFamily) {
// We've figured out what family the given name maps to, after any
// fontconfig subsitutions. Cache it to speed up future lookups.
mFcSubstituteCache.Put(familyToFind, foundFamily);
return foundFamily;
}
}

Просмотреть файл

@ -256,6 +256,9 @@ protected:
// caching generic/lang ==> font family
nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> mGenericMappings;
// caching family lookups as found by FindFamily after resolving substitutions
nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> mFcSubstituteCache;
nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
nsCountedRef<FcConfig> mLastConfig;

Просмотреть файл

@ -1980,7 +1980,7 @@ gfxWindowsPlatform::InitD3D11Devices()
if (FAILED(hr)) {
// This should always succeed... in theory.
gfxCriticalError() << "Failed to initialize WARP D3D11 device!" << hr;
gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
return;
}

Просмотреть файл

@ -12,8 +12,6 @@ ifneq ($(make_min_ver),$(firstword $(sort $(make_min_ver) $(MAKE_VERSION))))
$(error GNU Make $(make_min_ver) or higher is required)
endif
TOPLEVEL_BUILD := 1
run_for_side_effects := $(shell echo 'MAKE: $(MAKE)')
ifdef JS_HAS_CTYPES

1
js/src/aclocal.m4 поставляемый
Просмотреть файл

@ -32,6 +32,7 @@ builtin(include, ../../build/autoconf/winsdk.m4)dnl
builtin(include, ../../build/autoconf/icu.m4)dnl
builtin(include, ../../build/autoconf/ffi.m4)dnl
builtin(include, ../../build/autoconf/clang-plugin.m4)dnl
builtin(include, ../../build/autoconf/alloc.m4)dnl
define([__MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
define([AC_INIT_PREPARE],

Просмотреть файл

@ -3847,18 +3847,9 @@ dnl ========================================================
dnl JavaScript shell
dnl ========================================================
MALLOC_HEADERS="malloc.h malloc_np.h malloc/malloc.h sys/malloc.h"
MALLOC_H=
MOZ_CHECK_ALLOCATOR
for file in $MALLOC_HEADERS; do
MOZ_CHECK_HEADER($file, [MALLOC_H=$file])
if test "$MALLOC_H" != ""; then
AC_DEFINE_UNQUOTED(MALLOC_H, <$MALLOC_H>)
break
fi
done
AC_CHECK_FUNCS(setlocale localeconv malloc_size malloc_usable_size)
AC_CHECK_FUNCS(setlocale localeconv)
AC_SUBST(MOZILLA_VERSION)

Просмотреть файл

@ -8,10 +8,17 @@ loadRelativeToScript('CFG.js');
var sourceRoot = (os.getenv('SOURCE') || '') + '/'
var functionName;
var functionBodies;
if (typeof scriptArgs[0] != 'string' || typeof scriptArgs[1] != 'string')
throw "Usage: analyzeRoots.js <gcFunctions.lst> <gcEdges.txt> <suppressedFunctions.lst> <gcTypes.txt> [start end [tmpfile]]";
throw "Usage: analyzeRoots.js [-f function_name] <gcFunctions.lst> <gcEdges.txt> <suppressedFunctions.lst> <gcTypes.txt> [start end [tmpfile]]";
var theFunctionNameToFind;
if (scriptArgs[0] == '--function') {
theFunctionNameToFind = scriptArgs[1];
scriptArgs = scriptArgs.slice(2);
}
var gcFunctionsFile = scriptArgs[0];
var gcEdgesFile = scriptArgs[1];
@ -209,7 +216,7 @@ function edgeTakesVariableAddress(edge, variable)
function edgeKillsVariable(edge, variable)
{
// Direct assignments kill their lhs.
// Direct assignments kill their lhs: var = value
if (edge.Kind == "Assign") {
var lhs = edge.Exp[0];
if (lhs.Kind == "Var" && sameVariable(lhs.Variable, variable))
@ -296,26 +303,48 @@ function edgeCanGC(edge)
return indirectCallCannotGC(functionName, varName) ? null : "*" + varName;
}
function variableUsePrecedesGC(suppressed, variable, worklist)
// Search recursively through predecessors from a variable use, returning
// whether a GC call is reachable (in the reverse direction; this means that
// the variable use is reachable from the GC call, and therefore the variable
// is live after the GC call), along with some additional information. What
// info we want depends on whether the variable turns out to be live across any
// GC call. We are looking for both hazards (unrooted variables live across GC
// calls) and unnecessary roots (rooted variables that have no GC calls in
// their live ranges.)
//
// If not:
//
// - 'minimumUse': the earliest point in each body that uses the variable, for
// reporting on unnecessary roots.
//
// If so:
//
// - 'why': a path from the GC call to a use of the variable after the GC
// call, chained through a 'why' field in the returned edge descriptor
//
// - 'gcInfo': a direct pointer to the GC call edge
//
function findGCBeforeVariableUse(suppressed, variable, worklist)
{
// Scan through all edges preceding an unrooted variable use, using an
// explicit worklist. A worklist contains an incoming edge together with a
// description of where it or one of its successors GC'd (if any).
// explicit worklist, looking for a GC call. A worklist contains an
// incoming edge together with a description of where it or one of its
// successors GC'd (if any).
while (worklist.length) {
var entry = worklist.pop();
var body = entry.body, ppoint = entry.ppoint;
var { body, ppoint, gcInfo } = entry;
if (body.seen) {
if (ppoint in body.seen) {
var seenEntry = body.seen[ppoint];
if (!entry.gcInfo || seenEntry.gcInfo)
if (!gcInfo || seenEntry.gcInfo)
continue;
}
} else {
body.seen = [];
}
body.seen[ppoint] = {body:body, gcInfo:entry.gcInfo};
body.seen[ppoint] = {body: body, gcInfo: gcInfo};
if (ppoint == body.Index[0]) {
if (body.BlockId.Kind == "Loop") {
@ -327,17 +356,17 @@ function variableUsePrecedesGC(suppressed, variable, worklist)
if (sameBlockId(xbody.BlockId, parent.BlockId)) {
assert(!found);
found = true;
worklist.push({body:xbody, ppoint:parent.Index,
gcInfo:entry.gcInfo, why:entry});
worklist.push({body: xbody, ppoint: parent.Index,
gcInfo: gcInfo, why: entry});
}
}
assert(found);
}
}
} else if (variable.Kind == "Arg" && entry.gcInfo) {
} else if (variable.Kind == "Arg" && gcInfo) {
// The scope of arguments starts at the beginning of the
// function
return {gcInfo:entry.gcInfo, why:entry};
return {gcInfo: gcInfo, why: entry};
}
}
@ -348,31 +377,45 @@ function variableUsePrecedesGC(suppressed, variable, worklist)
for (var edge of predecessors[ppoint]) {
var source = edge.Index[0];
if (edgeKillsVariable(edge, variable)) {
if (entry.gcInfo)
return {gcInfo: entry.gcInfo, why: {body:body, ppoint:source, gcInfo:entry.gcInfo, why:entry } }
var edge_kills = edgeKillsVariable(edge, variable);
var edge_uses = edgeUsesVariable(edge, variable, body);
if (edge_kills || edge_uses) {
if (!body.minimumUse || source < body.minimumUse)
body.minimumUse = source;
}
if (edge_kills) {
// This is a beginning of the variable's live range. If we can
// reach a GC call from here, then we're done -- we have a path
// from the beginning of the live range, through the GC call,
// to a use after the GC call that proves its live range
// extends at least that far.
if (gcInfo)
return {gcInfo: gcInfo, why: {body: body, ppoint: source, gcInfo: gcInfo, why: entry } }
// Otherwise, we want to continue searching for the true
// minimumUse, for use in reporting unnecessary rooting, but we
// truncate this particular branch of the search at this edge.
continue;
}
var gcInfo = entry.gcInfo;
if (!gcInfo && !(source in body.suppressed) && !suppressed) {
var gcName = edgeCanGC(edge, body);
if (gcName)
gcInfo = {name:gcName, body:body, ppoint:source};
}
if (edgeUsesVariable(edge, variable, body)) {
if (edge_uses) {
// The live range starts at least this far back, so we're done
// for the same reason as with edge_kills.
if (gcInfo)
return {gcInfo:gcInfo, why:entry};
if (!body.minimumUse || source < body.minimumUse)
body.minimumUse = source;
}
if (edge.Kind == "Loop") {
// propagate to exit points of the loop body, in addition to the
// predecessor of the loop edge itself.
// Additionally propagate the search into a loop body, starting
// with the exit point.
var found = false;
for (var xbody of functionBodies) {
if (sameBlockId(xbody.BlockId, edge.BlockId)) {
@ -385,6 +428,8 @@ function variableUsePrecedesGC(suppressed, variable, worklist)
assert(found);
break;
}
// Propagate the search to the predecessors of this edge.
worklist.push({body:body, ppoint:source, gcInfo:gcInfo, why:entry});
}
}
@ -407,14 +452,21 @@ function variableLiveAcrossGC(suppressed, variable)
continue;
for (var edge of body.PEdge) {
var usePoint = edgeUsesVariable(edge, variable, body);
// Example for !edgeKillsVariable:
//
// JSObject* obj = NewObject();
// cangc();
// obj = NewObject(); <-- uses 'obj', but kills previous value
//
if (usePoint && !edgeKillsVariable(edge, variable)) {
// Found a use, possibly after a GC.
var worklist = [{body:body, ppoint:usePoint, gcInfo:null, why:null}];
var call = variableUsePrecedesGC(suppressed, variable, worklist);
if (call) {
call.afterGCUse = usePoint;
return call;
}
var call = findGCBeforeVariableUse(suppressed, variable, worklist);
if (!call)
continue;
call.afterGCUse = usePoint;
return call;
}
}
}
@ -635,24 +687,10 @@ var end = Math.min(minStream + each * batch - 1, maxStream);
var theFunctionNameToFind;
// var start = end = 12345;
for (var nameIndex = start; nameIndex <= end; nameIndex++) {
var name = xdb.read_key(nameIndex);
var functionName = name.readString();
var data = xdb.read_entry(name);
xdb.free_string(name);
var json = data.readString();
xdb.free_string(data);
function process(name, json) {
functionName = name;
functionBodies = JSON.parse(json);
if (theFunctionNameToFind) {
if (functionName == theFunctionNameToFind) {
printErr("nameIndex = " + nameIndex);
quit(1);
} else {
continue;
}
}
for (var body of functionBodies)
body.suppressed = [];
for (var body of functionBodies) {
@ -661,3 +699,21 @@ for (var nameIndex = start; nameIndex <= end; nameIndex++) {
}
processBodies(functionName);
}
if (theFunctionNameToFind) {
var data = xdb.read_entry(theFunctionNameToFind);
var json = data.readString();
process(theFunctionNameToFind, json);
xdb.free_string(data);
quit(0);
}
for (var nameIndex = start; nameIndex <= end; nameIndex++) {
var name = xdb.read_key(nameIndex);
var functionName = name.readString();
var data = xdb.read_entry(name);
xdb.free_string(name);
var json = data.readString();
process(functionName, json);
xdb.free_string(data);
}

Просмотреть файл

@ -1,3 +1,6 @@
if (!this.SharedArrayBuffer)
quit(0);
function m(stdlib, ffi, heap) {
"use asm";
var HEAP32 = new stdlib.SharedInt32Array(heap);

Просмотреть файл

@ -0,0 +1,13 @@
// |jit-test| error:ReferenceError
(function() {
var $10=0;
while (1) {
switch (stack.label & 2) {
case 1:
return $8|0;
case 49:
if ($10) {}
}
}
})()()

Просмотреть файл

@ -171,7 +171,7 @@ void EnableIonDebugAsyncLogging();
class GraphSpewer
{
public:
GraphSpewer(TempAllocator *alloc) { }
explicit GraphSpewer(TempAllocator *alloc) { }
bool isSpewing() { return false; }
void init(MIRGraph* graph, JSScript* function) { }

Просмотреть файл

@ -3335,8 +3335,8 @@ RangeAnalysis::prepareForUCE(bool* shouldRemoveDeadCode)
return tryRemovingGuards();
}
bool RangeAnalysis::tryRemovingGuards() {
bool RangeAnalysis::tryRemovingGuards()
{
MDefinitionVector guards(alloc());
for (ReversePostorderIterator block = graph_.rpoBegin(); block != graph_.rpoEnd(); block++) {
@ -3344,6 +3344,7 @@ bool RangeAnalysis::tryRemovingGuards() {
if (!iter->isGuardRangeBailouts())
continue;
iter->setInWorklist();
if (!guards.append(*iter))
return false;
}
@ -3364,20 +3365,22 @@ bool RangeAnalysis::tryRemovingGuards() {
guard->setGuardRangeBailouts();
#endif
if (!guard->range())
continue;
if (!guard->isPhi()) {
if (!guard->range())
continue;
// Filter the range of the instruction based on its MIRType.
Range typeFilteredRange(guard);
// Filter the range of the instruction based on its MIRType.
Range typeFilteredRange(guard);
// If the output range is updated by adding the inner range,
// then the MIRType act as an effectful filter. As we do not know if
// this filtered Range might change or not the result of the
// previous comparison, we have to keep this instruction as a guard
// because it has to bailout in order to restrict the Range to its
// MIRType.
if (typeFilteredRange.update(guard->range()))
continue;
// If the output range is updated by adding the inner range,
// then the MIRType act as an effectful filter. As we do not know if
// this filtered Range might change or not the result of the
// previous comparison, we have to keep this instruction as a guard
// because it has to bailout in order to restrict the Range to its
// MIRType.
if (typeFilteredRange.update(guard->range()))
continue;
}
guard->setNotGuardRangeBailouts();
@ -3386,19 +3389,27 @@ bool RangeAnalysis::tryRemovingGuards() {
MDefinition* operand = guard->getOperand(op);
// Already marked.
if (operand->isGuardRangeBailouts())
if (operand->isInWorklist())
continue;
MOZ_ASSERT(!operand->isGuardRangeBailouts());
// No need to mark as a guard, since it is has already an even more
// restrictive flag set.
if (!DeadIfUnused(operand))
continue;
operand->setInWorklist();
operand->setGuardRangeBailouts();
if (!guards.append(operand))
return false;
}
}
for (size_t i = 0; i < guards.length(); i++) {
MDefinition* guard = guards[i];
guard->setNotInWorklist();
}
return true;
}

Просмотреть файл

@ -682,7 +682,7 @@ ValueNumberer::loopHasOptimizablePhi(MBasicBlock* header) const
// values from backedges.
for (MPhiIterator iter(header->phisBegin()), end(header->phisEnd()); iter != end; ++iter) {
MPhi* phi = *iter;
MOZ_ASSERT(phi->hasUses(), "Missed an unused phi");
MOZ_ASSERT_IF(!phi->hasUses(), !DeadIfUnused(phi));
if (phi->operandIfRedundant() || hasLeader(phi, header))
return true; // Phi can be simplified.

Просмотреть файл

@ -267,6 +267,10 @@ static const JSFunctionSpecWithHelp osfile_functions[] = {
" Read filename into returned string. Filename is relative to the directory\n"
" containing the current script."),
JS_FS_HELP_END
};
static const JSFunctionSpecWithHelp osfile_unsafe_functions[] = {
JS_FN_HELP("redirect", osfile_redirect, 2, 0,
"redirect(stdoutFilename[, stderrFilename])",
" Redirect stdout and/or stderr to the named file. Pass undefined to avoid\n"
@ -566,6 +570,11 @@ DefineOS(JSContext* cx, HandleObject global, bool fuzzingSafe)
return false;
}
if (!fuzzingSafe) {
if (!JS_DefineFunctionsWithHelp(cx, osfile, osfile_unsafe_functions))
return false;
}
// For backwards compatibility, expose various os.file.* functions as
// direct methods on the global.
RootedValue val(cx);
@ -583,9 +592,11 @@ DefineOS(JSContext* cx, HandleObject global, bool fuzzingSafe)
for (auto pair : osfile_exports) {
if (!JS_GetProperty(cx, osfile, pair.src, &val))
return false;
RootedObject function(cx, &val.toObject());
if (!JS_DefineProperty(cx, global, pair.dst, function, 0))
return false;
if (val.isObject()) {
RootedObject function(cx, &val.toObject());
if (!JS_DefineProperty(cx, global, pair.dst, function, 0))
return false;
}
}
return true;

Просмотреть файл

@ -2393,7 +2393,8 @@ nsCSSOffsetState::InitOffsets(const LogicalSize& aPercentBasis,
// try to do anything like handling 'auto' widths,
// 'box-sizing', or 'auto' margins.
ComputedPhysicalPadding().SizeTo(0,0,0,0);
ComputedPhysicalBorderPadding() = tableFrame->GetIncludedOuterBCBorder();
SetComputedLogicalBorderPadding(
tableFrame->GetIncludedOuterBCBorder(mWritingMode));
}
// The margin is inherited to the outer table frame via

Просмотреть файл

@ -79,25 +79,26 @@ struct nsTableReflowState {
"nsTableReflowState should only be created for nsTableFrame");
nsTableFrame* table =
static_cast<nsTableFrame*>(reflowState.frame->FirstInFlow());
nsMargin borderPadding = table->GetChildAreaOffset(&reflowState);
WritingMode wm = aReflowState.GetWritingMode();
LogicalMargin borderPadding = table->GetChildAreaOffset(wm, &reflowState);
x = borderPadding.left + table->GetColSpacing(-1);
y = borderPadding.top; //cellspacing added during reflow
x = borderPadding.IStart(wm) + table->GetColSpacing(-1);
y = borderPadding.BStart(wm); //cellspacing added during reflow
availSize.width = aAvailWidth;
if (NS_UNCONSTRAINEDSIZE != availSize.width) {
int32_t colCount = table->GetColCount();
availSize.width -= borderPadding.left + borderPadding.right
+ table->GetColSpacing(-1)
+ table->GetColSpacing(colCount);
availSize.width -= borderPadding.IStartEnd(wm) +
table->GetColSpacing(-1) +
table->GetColSpacing(colCount);
availSize.width = std::max(0, availSize.width);
}
availSize.height = aAvailHeight;
if (NS_UNCONSTRAINEDSIZE != availSize.height) {
availSize.height -= borderPadding.top + borderPadding.bottom
+ table->GetRowSpacing(-1)
+ table->GetRowSpacing(table->GetRowCount());
availSize.height -= borderPadding.BStartEnd(wm) +
table->GetRowSpacing(-1) +
table->GetRowSpacing(table->GetRowCount());
availSize.height = std::max(0, availSize.height);
}
}
@ -1350,7 +1351,8 @@ nsTableFrame::GetDeflationForBackground(nsPresContext* aPresContext) const
!IsBorderCollapse())
return nsMargin(0,0,0,0);
return GetOuterBCBorder();
WritingMode wm = GetWritingMode();
return GetOuterBCBorder(wm).GetPhysicalMargin(wm);
}
// XXX We don't put the borders and backgrounds in tree order like we should.
@ -1418,10 +1420,10 @@ nsTableFrame::GetLogicalSkipSides(const nsHTMLReflowState* aReflowState) const
}
void
nsTableFrame::SetColumnDimensions(nscoord aHeight,
const nsMargin& aBorderPadding)
nsTableFrame::SetColumnDimensions(nscoord aHeight, WritingMode aWM,
const LogicalMargin& aBorderPadding)
{
nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom +
nscoord colHeight = aHeight -= aBorderPadding.BStartEnd(aWM) +
GetRowSpacing(-1) +
GetRowSpacing(GetRowCount());
@ -1431,8 +1433,8 @@ nsTableFrame::SetColumnDimensions(nscoord aHeight,
int32_t colX =tableIsLTR ? 0 : std::max(0, GetColCount() - 1);
nscoord cellSpacingX = GetColSpacing(colX);
int32_t tableColIncr = tableIsLTR ? 1 : -1;
nsPoint colGroupOrigin(aBorderPadding.left + GetColSpacing(-1),
aBorderPadding.top + GetRowSpacing(-1));
nsPoint colGroupOrigin(aBorderPadding.IStart(aWM) + GetColSpacing(-1),
aBorderPadding.BStart(aWM) + GetRowSpacing(-1));
while (colGroupFrame) {
MOZ_ASSERT(colGroupFrame->GetType() == nsGkAtoms::tableColGroupFrame);
nscoord colGroupWidth = 0;
@ -1552,8 +1554,9 @@ nsTableFrame::IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext)
result.hPadding = 0;
result.hPctPadding = 0;
nsMargin outerBC = GetIncludedOuterBCBorder();
result.hBorder = outerBC.LeftRight();
WritingMode wm = GetWritingMode();
LogicalMargin outerBC = GetIncludedOuterBCBorder(wm);
result.hBorder = outerBC.IStartEnd(wm);
}
return result;
@ -1785,6 +1788,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
DO_GLOBAL_REFLOW_COUNT("nsTableFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
bool isPaginated = aPresContext->IsPaginated();
WritingMode wm = aReflowState.GetWritingMode();
aStatus = NS_FRAME_COMPLETE;
if (!GetPrevInFlow() && !mTableLayoutStrategy) {
@ -1877,8 +1881,8 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
// if there is an incomplete child, then set the desired height to include it but not the next one
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
aDesiredSize.Height() = borderPadding.bottom + GetRowSpacing(GetRowCount()) +
LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
aDesiredSize.Height() = borderPadding.BEnd(wm) + GetRowSpacing(GetRowCount()) +
lastChildReflowed->GetNormalRect().YMost();
}
haveDesiredHeight = true;
@ -1902,11 +1906,11 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
ProcessRowInserted(aDesiredSize.Height());
}
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
SetColumnDimensions(aDesiredSize.Height(), borderPadding);
LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
SetColumnDimensions(aDesiredSize.Height(), wm, borderPadding);
if (NeedToCollapse() &&
(NS_UNCONSTRAINEDSIZE != aReflowState.AvailableWidth())) {
AdjustForCollapsingRowsCols(aDesiredSize, borderPadding);
AdjustForCollapsingRowsCols(aDesiredSize, wm, borderPadding);
}
// If there are any relatively-positioned table parts, we need to reflow their
@ -1918,8 +1922,8 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
if (!ShouldApplyOverflowClipping(this, aReflowState.mStyleDisplay)) {
// collapsed border may leak out
nsMargin bcMargin = GetExcludedOuterBCBorder();
tableRect.Inflate(bcMargin);
LogicalMargin bcMargin = GetExcludedOuterBCBorder(wm);
tableRect.Inflate(bcMargin.GetPhysicalMargin(wm));
}
aDesiredSize.mOverflowAreas.UnionAllWith(tableRect);
@ -2007,8 +2011,9 @@ nsTableFrame::UpdateOverflow()
// As above in Reflow, make sure the table overflow area includes the table
// rect, and check for collapsed borders leaking out.
if (!ShouldApplyOverflowClipping(this, StyleDisplay())) {
nsMargin bcMargin = GetExcludedOuterBCBorder();
bounds.Inflate(bcMargin);
WritingMode wm = GetWritingMode();
LogicalMargin bcMargin = GetExcludedOuterBCBorder(wm);
bounds.Inflate(bcMargin.GetPhysicalMargin(wm));
}
nsOverflowAreas overflowAreas(bounds, bounds);
@ -2123,7 +2128,8 @@ nsTableFrame::PushChildren(const RowGroupArray& aRowGroups,
// reflow so that it has no effect on the calculations of reflow.
void
nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
nsMargin aBorderPadding)
const WritingMode aWM,
const LogicalMargin& aBorderPadding)
{
nscoord yTotalOffset = 0; // total offset among all rows in all row groups
@ -2137,7 +2143,7 @@ nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
OrderRowGroups(rowGroups);
nsTableFrame* firstInFlow = static_cast<nsTableFrame*>(FirstInFlow());
nscoord width = firstInFlow->GetCollapsedWidth(aBorderPadding);
nscoord width = firstInFlow->GetCollapsedWidth(aWM, aBorderPadding);
nscoord rgWidth = width - GetColSpacing(-1) -
GetColSpacing(GetColCount());
nsOverflowAreas overflow;
@ -2158,11 +2164,12 @@ nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
nscoord
nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
nsTableFrame::GetCollapsedWidth(const WritingMode aWM,
const LogicalMargin& aBorderPadding)
{
NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedWidth called on next in flow");
nscoord width = GetColSpacing(GetColCount());
width += aBorderPadding.left + aBorderPadding.right;
width += aBorderPadding.IStartEnd(aWM);
for (nsIFrame* groupFrame : mColGroups) {
const nsStyleVisibility* groupVis = groupFrame->StyleVisibility();
bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
@ -2550,7 +2557,8 @@ nsTableFrame::GetUsedBorder() const
if (!IsBorderCollapse())
return nsContainerFrame::GetUsedBorder();
return GetIncludedOuterBCBorder();
WritingMode wm = GetWritingMode();
return GetIncludedOuterBCBorder(wm).GetPhysicalMargin(wm);
}
/* virtual */ nsMargin
@ -2595,74 +2603,72 @@ DivideBCBorderSize(BCPixelSize aPixelSize,
aLargeHalf = aPixelSize - aSmallHalf;
}
nsMargin
nsTableFrame::GetOuterBCBorder() const
LogicalMargin
nsTableFrame::GetOuterBCBorder(const WritingMode aWM) const
{
if (NeedToCalcBCBorders())
const_cast<nsTableFrame*>(this)->CalcBCBorders();
nsMargin border(0, 0, 0, 0);
int32_t p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData = GetBCProperty();
if (propData) {
border.top = BC_BORDER_START_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right = BC_BORDER_END_HALF_COORD(p2t, propData->mRightBorderWidth);
border.bottom = BC_BORDER_END_HALF_COORD(p2t, propData->mBottomBorderWidth);
border.left = BC_BORDER_START_HALF_COORD(p2t, propData->mLeftBorderWidth);
return LogicalMargin(
aWM,
BC_BORDER_START_HALF_COORD(p2t, propData->mTopBorderWidth),
BC_BORDER_END_HALF_COORD(p2t, propData->mRightBorderWidth),
BC_BORDER_END_HALF_COORD(p2t, propData->mBottomBorderWidth),
BC_BORDER_START_HALF_COORD(p2t, propData->mLeftBorderWidth));
}
return border;
return LogicalMargin(GetWritingMode());
}
nsMargin
nsTableFrame::GetIncludedOuterBCBorder() const
LogicalMargin
nsTableFrame::GetIncludedOuterBCBorder(const WritingMode aWM) const
{
if (NeedToCalcBCBorders())
const_cast<nsTableFrame*>(this)->CalcBCBorders();
nsMargin border(0, 0, 0, 0);
int32_t p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData = GetBCProperty();
if (propData) {
border.top += BC_BORDER_START_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right += BC_BORDER_END_HALF_COORD(p2t, propData->mRightCellBorderWidth);
border.bottom += BC_BORDER_END_HALF_COORD(p2t, propData->mBottomBorderWidth);
border.left += BC_BORDER_START_HALF_COORD(p2t, propData->mLeftCellBorderWidth);
return LogicalMargin(
aWM,
BC_BORDER_START_HALF_COORD(p2t, propData->mTopBorderWidth),
BC_BORDER_END_HALF_COORD(p2t, propData->mRightCellBorderWidth),
BC_BORDER_END_HALF_COORD(p2t, propData->mBottomBorderWidth),
BC_BORDER_START_HALF_COORD(p2t, propData->mLeftCellBorderWidth));
}
return border;
return LogicalMargin(GetWritingMode());
}
nsMargin
nsTableFrame::GetExcludedOuterBCBorder() const
LogicalMargin
nsTableFrame::GetExcludedOuterBCBorder(const WritingMode aWM) const
{
return GetOuterBCBorder() - GetIncludedOuterBCBorder();
return GetOuterBCBorder(aWM) - GetIncludedOuterBCBorder(aWM);
}
static
void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState,
nsStyleContext& aStyleContext,
nsMargin& aBorderPadding)
static LogicalMargin
GetSeparateModelBorderPadding(const WritingMode aWM,
const nsHTMLReflowState* aReflowState,
nsStyleContext* aStyleContext)
{
// XXXbz Either we _do_ have a reflow state and then we can use its
// mComputedBorderPadding or we don't and then we get the padding
// wrong!
const nsStyleBorder* border = aStyleContext.StyleBorder();
aBorderPadding = border->GetComputedBorder();
const nsStyleBorder* border = aStyleContext->StyleBorder();
LogicalMargin borderPadding(aWM, border->GetComputedBorder());
if (aReflowState) {
aBorderPadding += aReflowState->ComputedPhysicalPadding();
borderPadding += aReflowState->ComputedLogicalPadding();
}
return borderPadding;
}
nsMargin
nsTableFrame::GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const
LogicalMargin
nsTableFrame::GetChildAreaOffset(const WritingMode aWM,
const nsHTMLReflowState* aReflowState) const
{
nsMargin offset(0,0,0,0);
if (IsBorderCollapse()) {
offset = GetIncludedOuterBCBorder();
}
else {
GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset);
}
return offset;
return IsBorderCollapse() ? GetIncludedOuterBCBorder(aWM) :
GetSeparateModelBorderPadding(aWM, aReflowState, mStyleContext);
}
void
@ -3218,7 +3224,8 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState,
aDesiredSize.Height() = 0;
return;
}
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
WritingMode wm = aReflowState.GetWritingMode();
LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
// get the natural height based on the last child's (row group) rect
RowGroupArray rowGroups;
@ -3238,7 +3245,7 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState,
}
int32_t rowCount = cellMap->GetRowCount();
int32_t colCount = cellMap->GetColCount();
nscoord desiredHeight = borderPadding.top + borderPadding.bottom;
nscoord desiredHeight = borderPadding.BStartEnd(wm);
if (rowCount > 0 && colCount > 0) {
desiredHeight += GetRowSpacing(-1);
for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) {
@ -3301,7 +3308,8 @@ void
nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
nscoord aAmount)
{
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
WritingMode wm = aReflowState.GetWritingMode();
LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
RowGroupArray rowGroups;
OrderRowGroups(rowGroups);
@ -3311,7 +3319,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
// height, and base the pct on the table height. If the row group had a computed
// height, then this was already done in nsTableRowGroupFrame::CalculateRowHeights
nscoord pctBasis = aReflowState.ComputedHeight() - GetRowSpacing(-1, GetRowCount());
nscoord yOriginRG = borderPadding.top + GetRowSpacing(0);
nscoord yOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0);
nscoord yEndRG = yOriginRG;
uint32_t rgX;
for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
@ -3449,7 +3457,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
}
// allocate the extra height to the unstyled row groups and rows
nscoord heightToDistribute = aAmount - amountUsed;
yOriginRG = borderPadding.top + GetRowSpacing(-1);
yOriginRG = borderPadding.BStart(wm) + GetRowSpacing(-1);
yEndRG = yOriginRG;
for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
@ -3726,8 +3734,9 @@ nsTableFrame::CalcBorderBoxHeight(const nsHTMLReflowState& aState)
{
nscoord height = aState.ComputedHeight();
if (NS_AUTOHEIGHT != height) {
nsMargin borderPadding = GetChildAreaOffset(&aState);
height += borderPadding.top + borderPadding.bottom;
WritingMode wm = aState.GetWritingMode();
LogicalMargin borderPadding = GetChildAreaOffset(wm, &aState);
height += borderPadding.BStartEnd(wm);
}
height = std::max(0, height);
@ -6386,9 +6395,10 @@ BCPaintBorderIterator::BCPaintBorderIterator(nsTableFrame* aTable)
, mTableWM(aTable->StyleContext())
{
mVerInfo = nullptr;
nsMargin childAreaOffset = mTable->GetChildAreaOffset(nullptr);
LogicalMargin childAreaOffset = mTable->GetChildAreaOffset(mTableWM, nullptr);
// y position of first row in damage area
mInitialOffsetY = mTable->GetPrevInFlow() ? 0 : childAreaOffset.top;
mInitialOffsetY =
mTable->GetPrevInFlow() ? 0 : childAreaOffset.BStart(mTableWM);
mNumTableRows = mTable->GetRowCount();
mNumTableCols = mTable->GetColCount();
@ -6465,15 +6475,16 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect)
return false;
int32_t leftCol, rightCol; // columns are in the range [leftCol, rightCol)
nsMargin childAreaOffset = mTable->GetChildAreaOffset(nullptr);
LogicalMargin childAreaOffset = mTable->GetChildAreaOffset(mTableWM, nullptr);
if (mTableWM.IsBidiLTR()) {
mInitialOffsetX = childAreaOffset.left; // x position of first col in
// damage area
// x position of first col in damage area
mInitialOffsetX = childAreaOffset.IStart(mTableWM);
leftCol = 0;
rightCol = mNumTableCols;
} else {
// x position of first col in damage area
mInitialOffsetX = mTable->GetRect().width - childAreaOffset.right;
mInitialOffsetX =
mTable->GetRect().width - childAreaOffset.IStart(mTableWM);
leftCol = mNumTableCols-1;
rightCol = -1;
}
@ -6509,7 +6520,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect)
}
if (!mTableWM.IsBidiLTR()) {
uint32_t temp;
mInitialOffsetX = mTable->GetRect().width - childAreaOffset.right;
mInitialOffsetX =
mTable->GetRect().width - childAreaOffset.IStart(mTableWM);
temp = startColIndex; startColIndex = endColIndex; endColIndex = temp;
for (uint32_t column = 0; column < startColIndex; column++) {
nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(column);

Просмотреть файл

@ -25,6 +25,10 @@ class nsTableRowFrame;
class nsTableColGroupFrame;
class nsITableLayoutStrategy;
class nsStyleContext;
namespace mozilla {
class WritingMode;
class LogicalMargin;
}
struct nsTableReflowState;
struct BCPropertyData;
@ -123,6 +127,8 @@ enum nsTableColType {
class nsTableFrame : public nsContainerFrame
{
typedef mozilla::image::DrawResult DrawResult;
typedef mozilla::WritingMode WritingMode;
typedef mozilla::LogicalMargin LogicalMargin;
public:
NS_DECL_QUERYFRAME_TARGET(nsTableFrame)
@ -206,7 +212,8 @@ public:
virtual nsMargin GetUsedMargin() const override;
// Get the offset from the border box to the area where the row groups fit
nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
LogicalMargin GetChildAreaOffset(const WritingMode aWM,
const nsHTMLReflowState* aReflowState) const;
/** helper method to find the table parent of any table frame object */
static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
@ -273,18 +280,18 @@ public:
* the table) of the largest segment (?) of border-collapsed border on
* the table on each side, or 0 for non border-collapsed tables.
*/
nsMargin GetOuterBCBorder() const;
LogicalMargin GetOuterBCBorder(const WritingMode aWM) const;
/** Same as above, but only if it's included from the border-box width
* of the table.
*/
nsMargin GetIncludedOuterBCBorder() const;
LogicalMargin GetIncludedOuterBCBorder(const WritingMode aWM) const;
/** Same as above, but only if it's excluded from the border-box width
* of the table. This is the area that leaks out into the margin
* (or potentially past it, if there is no margin).
*/
nsMargin GetExcludedOuterBCBorder() const;
LogicalMargin GetExcludedOuterBCBorder(const WritingMode aWM) const;
/**
* In quirks mode, the size of the table background is reduced
@ -632,7 +639,8 @@ protected:
* on columns and colgroups
* @param aBorderPadding the border and padding of the table
*/
nscoord GetCollapsedWidth(nsMargin aBorderPadding);
nscoord GetCollapsedWidth(const WritingMode aWM,
const LogicalMargin& aBorderPadding);
/** Adjust the table for visibility.collapse set on rowgroups, rows,
@ -641,7 +649,8 @@ protected:
* @param aBorderPadding the border and padding of the table
*/
void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
nsMargin aBorderPadding);
const WritingMode aWM,
const LogicalMargin& aBorderPadding);
/** FixupPositionedTableParts is called at the end of table reflow to reflow
* the absolutely positioned descendants of positioned table parts. This is
@ -801,8 +810,8 @@ protected:
void ExpandBCDamageArea(mozilla::TableArea& aRect) const;
void SetColumnDimensions(nscoord aHeight,
const nsMargin& aReflowState);
void SetColumnDimensions(nscoord aHeight, WritingMode aWM,
const LogicalMargin& aBorderPadding);
int32_t CollectRows(nsIFrame* aFrame,
nsTArray<nsTableRowFrame*>& aCollection);

Просмотреть файл

@ -242,7 +242,9 @@ nsTableOuterFrame::InitChildReflowState(nsPresContext& aPresContext,
nsMargin* pCollapsePadding = nullptr;
if (aReflowState.frame == InnerTableFrame() &&
InnerTableFrame()->IsBorderCollapse()) {
collapseBorder = InnerTableFrame()->GetIncludedOuterBCBorder();
WritingMode wm = aReflowState.GetWritingMode();
LogicalMargin border = InnerTableFrame()->GetIncludedOuterBCBorder(wm);
collapseBorder = border.GetPhysicalMargin(wm);
pCollapseBorder = &collapseBorder;
pCollapsePadding = &collapsePadding;
}

Просмотреть файл

@ -6514,13 +6514,8 @@ malloc_good_size_impl(size_t size)
}
#if defined(MOZ_MEMORY_ANDROID) && (ANDROID_VERSION < 19)
MOZ_MEMORY_API size_t
malloc_usable_size_impl(void *ptr)
#else
MOZ_MEMORY_API size_t
malloc_usable_size_impl(const void *ptr)
#endif
malloc_usable_size_impl(MALLOC_USABLE_SIZE_CONST_PTR void *ptr)
{
DARWIN_ONLY(return (szone->size)(szone, ptr));

Просмотреть файл

@ -9,6 +9,6 @@ SOURCES += [
'dummy_replace_malloc.c',
]
SharedLibrary('replace_malloc')
SharedLibrary('dummy_replace_malloc')
DISABLE_STL_WRAPPING = True

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше