зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to b2g-inbound
This commit is contained in:
Коммит
13d8c8bc5a
|
@ -455,7 +455,8 @@ DocAccessible::Shutdown()
|
|||
mChildDocuments.Clear();
|
||||
|
||||
// XXX thinking about ordering?
|
||||
if (IPCAccessibilityActive()) {
|
||||
if (mIPCDoc) {
|
||||
MOZ_ASSERT(IPCAccessibilityActive());
|
||||
mIPCDoc->Shutdown();
|
||||
MOZ_ASSERT(!mIPCDoc);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
48
configure.in
48
configure.in
|
@ -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, ¶m);
|
||||
gl->fGetSamplerParameteriv(sampler->mGLName, pname, ¶m);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
@ -82,7 +91,7 @@ WebGLContextUnchecked::GetSamplerParameterfv(WebGLSampler* sampler,
|
|||
|
||||
GLfloat param = 0.0f;
|
||||
gl->MakeCurrent();
|
||||
gl->fGetSamplerParameterfv(sampler->GLName(), pname, ¶m);
|
||||
gl->fGetSamplerParameterfv(sampler->mGLName, pname, ¶m);
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче