Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2014-03-17 13:16:53 -04:00
commit 6598f49d2f
50 changed files with 360 additions and 180 deletions

View File

@ -44,8 +44,12 @@ endif
# by GDB when we debug executables there. # by GDB when we debug executables there.
# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir. # NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
GDBINIT_FILES := $(topsrcdir)/.gdbinit GDBINIT_FILES := $(topsrcdir)/.gdbinit
GDBINIT_OBJDIR_FILES = $(topsrcdir)/.gdbinit
GDBINIT_DEST = $(FINAL_TARGET) GDBINIT_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += GDBINIT
# needs to be absolute to be distinct from $(topsrcdir)/.gdbinit
GDBINIT_OBJDIR_DEST = $(abspath $(DEPTH))
INSTALL_TARGETS += GDBINIT GDBINIT_OBJDIR
# Put a .lldbinit in the bin directory and the objdir, to be picked up # Put a .lldbinit in the bin directory and the objdir, to be picked up
# automatically by LLDB when we debug executables using either of those two # automatically by LLDB when we debug executables using either of those two

View File

@ -7888,7 +7888,13 @@ dnl ========================================================
dnl Check for pixman and cairo dnl Check for pixman and cairo
dnl ======================================================== dnl ========================================================
if test "$MOZ_WIDGET_TOOLKIT" = "gtk3" ; then
# cairo-gtk3 can be build with system-cairo only
MOZ_TREE_CAIRO=
else
MOZ_TREE_CAIRO=1 MOZ_TREE_CAIRO=1
fi
MOZ_ARG_ENABLE_BOOL(system-cairo, MOZ_ARG_ENABLE_BOOL(system-cairo,
[ --enable-system-cairo Use system cairo (located with pkgconfig)], [ --enable-system-cairo Use system cairo (located with pkgconfig)],
MOZ_TREE_CAIRO=, MOZ_TREE_CAIRO=,
@ -7978,6 +7984,9 @@ if test "$MOZ_TREE_CAIRO"; then
MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1) MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
fi fi
;; ;;
gtk3)
AC_MSG_ERROR([cairo-gtk3 toolkit is incompatible with in-tree cairo. Please add --enable-system-cairo to your build config.])
;;
esac esac
if test "$USE_FC_FREETYPE"; then if test "$USE_FC_FREETYPE"; then
FC_FONT_FEATURE="#define CAIRO_HAS_FC_FONT 1" FC_FONT_FEATURE="#define CAIRO_HAS_FC_FONT 1"

View File

@ -4,9 +4,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLBuffer.h" #include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "GLContext.h" #include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h" #include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#include "WebGLElementArrayCache.h"
using namespace mozilla; using namespace mozilla;
@ -55,6 +57,22 @@ WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t
mCache->BufferSubData(pos, ptr, update_size_in_bytes); mCache->BufferSubData(pos, ptr, update_size_in_bytes);
} }
size_t
WebGLBuffer::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
return aMallocSizeOf(this) + sizeOfCache;
}
bool
WebGLBuffer::Validate(GLenum type, uint32_t max_allowed,
size_t first, size_t count,
uint32_t* out_upperBound)
{
return mCache->Validate(type, max_allowed, first, count, out_upperBound);
}
JSObject* JSObject*
WebGLBuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) { WebGLBuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
return dom::WebGLBufferBinding::Wrap(cx, scope, this); return dom::WebGLBufferBinding::Wrap(cx, scope, this);

View File

@ -6,14 +6,12 @@
#ifndef WEBGLBUFFER_H_ #ifndef WEBGLBUFFER_H_
#define WEBGLBUFFER_H_ #define WEBGLBUFFER_H_
#include "WebGLObjectModel.h"
#include "WebGLElementArrayCache.h"
#include "GLDefs.h" #include "GLDefs.h"
#include "nsWrapperCache.h"
#include "mozilla/LinkedList.h" #include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h" #include "mozilla/MemoryReporting.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
#include "WebGLTypes.h"
namespace mozilla { namespace mozilla {
@ -32,10 +30,7 @@ public:
void Delete(); void Delete();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
return aMallocSizeOf(this) + sizeOfCache;
}
bool HasEverBeenBound() { return mHasEverBeenBound; } bool HasEverBeenBound() { return mHasEverBeenBound; }
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
@ -51,9 +46,8 @@ public:
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes); void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count) { bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count,
return mCache->Validate(type, max_allowed, first, count); uint32_t* out_upperBound);
}
WebGLContext *GetParentObject() const { WebGLContext *GetParentObject() const {
return Context(); return Context();

View File

@ -787,7 +787,8 @@ private:
bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info); bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
GLsizei primcount, const char* info); GLsizei primcount, const char* info,
GLuint* out_upperBound = nullptr);
bool DrawInstanced_check(const char* info); bool DrawInstanced_check(const char* info);
void Draw_cleanup(); void Draw_cleanup();

View File

@ -4,16 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h" #include "WebGLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLVertexArray.h"
#include "WebGLTexture.h"
#include "WebGLRenderbuffer.h"
#include "WebGLFramebuffer.h"
#include "WebGLUniformInfo.h"
#include "WebGLShader.h"
#include "WebGLProgram.h"
#include "GLContext.h" #include "GLContext.h"
#include "mozilla/CheckedInt.h"
#include "WebGLBuffer.h"
#include "WebGLFramebuffer.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "WebGLUniformInfo.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
using namespace mozilla; using namespace mozilla;
using namespace dom; using namespace dom;
@ -554,7 +556,9 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
} }
bool bool
WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, GLsizei primcount, const char* info) WebGLContext::DrawElements_check(GLsizei count, GLenum type,
WebGLintptr byteOffset, GLsizei primcount,
const char* info, GLuint* out_upperBound)
{ {
if (count < 0 || byteOffset < 0) { if (count < 0 || byteOffset < 0) {
ErrorInvalidValue("%s: negative count or offset", info); ErrorInvalidValue("%s: negative count or offset", info);
@ -620,7 +624,9 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
return false; return false;
} }
if (!mBoundVertexArray->mBoundElementArrayBuffer->ByteLength()) { WebGLBuffer& elemArrayBuffer = *mBoundVertexArray->mBoundElementArrayBuffer;
if (!elemArrayBuffer.ByteLength()) {
ErrorInvalidOperation("%s: bound element array buffer doesn't have any data", info); ErrorInvalidOperation("%s: bound element array buffer doesn't have any data", info);
return false; return false;
} }
@ -632,7 +638,7 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
return false; return false;
} }
if (uint32_t(checked_neededByteCount.value()) > mBoundVertexArray->mBoundElementArrayBuffer->ByteLength()) { if (uint32_t(checked_neededByteCount.value()) > elemArrayBuffer.ByteLength()) {
ErrorInvalidOperation("%s: bound element array buffer is too small for given count and offset", info); ErrorInvalidOperation("%s: bound element array buffer is too small for given count and offset", info);
return false; return false;
} }
@ -641,7 +647,7 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
return false; return false;
if (!mMaxFetchedVertices || if (!mMaxFetchedVertices ||
!mBoundVertexArray->mBoundElementArrayBuffer->Validate(type, mMaxFetchedVertices - 1, first, count)) !elemArrayBuffer.Validate(type, mMaxFetchedVertices - 1, first, count, out_upperBound))
{ {
ErrorInvalidOperation( ErrorInvalidOperation(
"%s: bound vertex attribute buffers do not have sufficient " "%s: bound vertex attribute buffers do not have sufficient "
@ -681,11 +687,21 @@ WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
if (!ValidateDrawModeEnum(mode, "drawElements: mode")) if (!ValidateDrawModeEnum(mode, "drawElements: mode"))
return; return;
if (!DrawElements_check(count, type, byteOffset, 1, "drawElements")) GLuint upperBound = UINT_MAX;
if (!DrawElements_check(count, type, byteOffset, 1, "drawElements",
&upperBound))
{
return; return;
}
SetupContextLossTimer(); SetupContextLossTimer();
if (gl->IsSupported(gl::GLFeature::draw_range_elements)) {
gl->fDrawRangeElements(mode, 0, upperBound,
count, type, reinterpret_cast<GLvoid*>(byteOffset));
} else {
gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset)); gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
}
Draw_cleanup(); Draw_cleanup();
} }

View File

@ -16,6 +16,24 @@
namespace mozilla { namespace mozilla {
static void
SetUpperBound(uint32_t* out_upperBound, uint32_t newBound)
{
if (!out_upperBound)
return;
*out_upperBound = newBound;
}
static void
UpdateUpperBound(uint32_t* out_upperBound, uint32_t newBound)
{
if (!out_upperBound)
return;
*out_upperBound = std::max(*out_upperBound, newBound);
}
/* /*
* WebGLElementArrayCacheTree contains most of the implementation of WebGLElementArrayCache, * WebGLElementArrayCacheTree contains most of the implementation of WebGLElementArrayCache,
* which performs WebGL element array buffer validation for drawElements. * which performs WebGL element array buffer validation for drawElements.
@ -227,7 +245,9 @@ public:
return ((numElements - 1) | sElementsPerLeafMask) + 1; return ((numElements - 1) | sElementsPerLeafMask) + 1;
} }
bool Validate(T maxAllowed, size_t firstLeaf, size_t lastLeaf) { bool Validate(T maxAllowed, size_t firstLeaf, size_t lastLeaf,
uint32_t* out_upperBound)
{
MOZ_ASSERT(!mInvalidated); MOZ_ASSERT(!mInvalidated);
size_t firstTreeIndex = TreeIndexForLeaf(firstLeaf); size_t firstTreeIndex = TreeIndexForLeaf(firstLeaf);
@ -240,13 +260,17 @@ public:
// final case where there is only 1 node to validate at the current tree level // final case where there is only 1 node to validate at the current tree level
if (lastTreeIndex == firstTreeIndex) { if (lastTreeIndex == firstTreeIndex) {
return mTreeData[firstTreeIndex] <= maxAllowed; const T& curData = mTreeData[firstTreeIndex];
UpdateUpperBound(out_upperBound, curData);
return curData <= maxAllowed;
} }
// if the first node at current tree level is a right node, handle it individually // if the first node at current tree level is a right node, handle it individually
// and replace it with its right neighbor, which is a left node // and replace it with its right neighbor, which is a left node
if (IsRightNode(firstTreeIndex)) { if (IsRightNode(firstTreeIndex)) {
if (mTreeData[firstTreeIndex] > maxAllowed) const T& curData = mTreeData[firstTreeIndex];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowed)
return false; return false;
firstTreeIndex = RightNeighborNode(firstTreeIndex); firstTreeIndex = RightNeighborNode(firstTreeIndex);
} }
@ -254,7 +278,9 @@ public:
// if the last node at current tree level is a left node, handle it individually // if the last node at current tree level is a left node, handle it individually
// and replace it with its left neighbor, which is a right node // and replace it with its left neighbor, which is a right node
if (IsLeftNode(lastTreeIndex)) { if (IsLeftNode(lastTreeIndex)) {
if (mTreeData[lastTreeIndex] > maxAllowed) const T& curData = mTreeData[lastTreeIndex];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowed)
return false; return false;
lastTreeIndex = LeftNeighborNode(lastTreeIndex); lastTreeIndex = LeftNeighborNode(lastTreeIndex);
} }
@ -490,10 +516,18 @@ void WebGLElementArrayCache::InvalidateTrees(size_t firstByte, size_t lastByte)
} }
template<typename T> template<typename T>
bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement, size_t countElements) { bool
WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
size_t countElements, uint32_t* out_upperBound)
{
SetUpperBound(out_upperBound, 0);
// if maxAllowed is >= the max T value, then there is no way that a T index could be invalid // if maxAllowed is >= the max T value, then there is no way that a T index could be invalid
if (maxAllowed >= std::numeric_limits<T>::max()) uint32_t maxTSize = std::numeric_limits<T>::max();
if (maxAllowed >= maxTSize) {
SetUpperBound(out_upperBound, maxTSize);
return true; return true;
}
T maxAllowedT(maxAllowed); T maxAllowedT(maxAllowed);
@ -515,8 +549,10 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
// fast exit path when the global maximum for the whole element array buffer // fast exit path when the global maximum for the whole element array buffer
// falls in the allowed range // falls in the allowed range
if (tree->GlobalMaximum() <= maxAllowedT) T globalMax = tree->GlobalMaximum();
if (globalMax <= maxAllowedT)
{ {
SetUpperBound(out_upperBound, globalMax);
return true; return true;
} }
@ -527,14 +563,18 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
size_t firstElementAdjustmentEnd = std::min(lastElement, size_t firstElementAdjustmentEnd = std::min(lastElement,
tree->LastElementUnderSameLeaf(firstElement)); tree->LastElementUnderSameLeaf(firstElement));
while (firstElement <= firstElementAdjustmentEnd) { while (firstElement <= firstElementAdjustmentEnd) {
if (elements[firstElement] > maxAllowedT) const T& curData = elements[firstElement];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowedT)
return false; return false;
firstElement++; firstElement++;
} }
size_t lastElementAdjustmentEnd = std::max(firstElement, size_t lastElementAdjustmentEnd = std::max(firstElement,
tree->FirstElementUnderSameLeaf(lastElement)); tree->FirstElementUnderSameLeaf(lastElement));
while (lastElement >= lastElementAdjustmentEnd) { while (lastElement >= lastElementAdjustmentEnd) {
if (elements[lastElement] > maxAllowedT) const T& curData = elements[lastElement];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowedT)
return false; return false;
lastElement--; lastElement--;
} }
@ -546,20 +586,29 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
// general case // general case
return tree->Validate(maxAllowedT, return tree->Validate(maxAllowedT,
tree->LeafForElement(firstElement), tree->LeafForElement(firstElement),
tree->LeafForElement(lastElement)); tree->LeafForElement(lastElement),
out_upperBound);
} }
bool WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed, size_t firstElement, size_t countElements) { bool
WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed,
size_t firstElement, size_t countElements,
uint32_t* out_upperBound)
{
if (type == LOCAL_GL_UNSIGNED_BYTE) if (type == LOCAL_GL_UNSIGNED_BYTE)
return Validate<uint8_t>(maxAllowed, firstElement, countElements); return Validate<uint8_t>(maxAllowed, firstElement, countElements, out_upperBound);
if (type == LOCAL_GL_UNSIGNED_SHORT) if (type == LOCAL_GL_UNSIGNED_SHORT)
return Validate<uint16_t>(maxAllowed, firstElement, countElements); return Validate<uint16_t>(maxAllowed, firstElement, countElements, out_upperBound);
if (type == LOCAL_GL_UNSIGNED_INT) if (type == LOCAL_GL_UNSIGNED_INT)
return Validate<uint32_t>(maxAllowed, firstElement, countElements); return Validate<uint32_t>(maxAllowed, firstElement, countElements, out_upperBound);
MOZ_ASSERT(false, "Invalid type.");
return false; return false;
} }
size_t WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t
WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
size_t uint8TreeSize = mUint8Tree ? mUint8Tree->SizeOfIncludingThis(aMallocSizeOf) : 0; size_t uint8TreeSize = mUint8Tree ? mUint8Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
size_t uint16TreeSize = mUint16Tree ? mUint16Tree->SizeOfIncludingThis(aMallocSizeOf) : 0; size_t uint16TreeSize = mUint16Tree ? mUint16Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
size_t uint32TreeSize = mUint32Tree ? mUint32Tree->SizeOfIncludingThis(aMallocSizeOf) : 0; size_t uint32TreeSize = mUint32Tree ? mUint32Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;

View File

@ -33,7 +33,8 @@ public:
bool BufferData(const void* ptr, size_t byteSize); bool BufferData(const void* ptr, size_t byteSize);
void BufferSubData(size_t pos, const void* ptr, size_t updateByteSize); void BufferSubData(size_t pos, const void* ptr, size_t updateByteSize);
bool Validate(GLenum type, uint32_t maxAllowed, size_t first, size_t count); bool Validate(GLenum type, uint32_t maxAllowed, size_t first, size_t count,
uint32_t* out_upperBound = nullptr);
template<typename T> template<typename T>
T Element(size_t i) const { return Elements<T>()[i]; } T Element(size_t i) const { return Elements<T>()[i]; }
@ -53,7 +54,8 @@ public:
private: private:
template<typename T> template<typename T>
bool Validate(uint32_t maxAllowed, size_t first, size_t count); bool Validate(uint32_t maxAllowed, size_t first, size_t count,
uint32_t* out_upperBound);
size_t ByteSize() const { size_t ByteSize() const {
return mByteSize; return mByteSize;

View File

@ -13,6 +13,7 @@
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/dom/TextTrack.h" #include "mozilla/dom/TextTrack.h"
#include "mozilla/Preferences.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -28,6 +29,12 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextTrackRegion) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextTrackRegion)
static bool RegionsEnabled(JSContext* cx, JSObject* obj)
{
return Preferences::GetBool("media.webvtt.enabled") &&
Preferences::GetBool("media.webvtt.regions.enabled");
}
virtual JSObject* WrapObject(JSContext* aCx, virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;

View File

@ -17,7 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=833386
<pre id="test"> <pre id="test">
<script class="testbody" type="text/javascript"> <script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]}, SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true],
["media.webvtt.regions.enabled", true]]},
function() { function() {
var video = document.createElement("video"); var video = document.createElement("video");
video.src = "seek.webm"; video.src = "seek.webm";

View File

@ -17,7 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=917945
<pre id="test"> <pre id="test">
<script class="testbody" type="text/javascript"> <script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]}, SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true],
["media.webvtt.regions.enabled", true]]},
function() { function() {
var video = document.createElement("video"); var video = document.createElement("video");
video.src = "seek.webm"; video.src = "seek.webm";

View File

@ -1118,7 +1118,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"VTTCue", "VTTCue",
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"VTTRegion", {name: "VTTRegion", pref: "media.webvtt.regions.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
"WaveShaperNode", "WaveShaperNode",
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -32,6 +32,7 @@ interface VTTCue : EventTarget {
attribute double startTime; attribute double startTime;
attribute double endTime; attribute double endTime;
attribute boolean pauseOnExit; attribute boolean pauseOnExit;
[Pref="media.webvtt.regions.enabled"]
attribute VTTRegion? region; attribute VTTRegion? region;
attribute DirectionSetting vertical; attribute DirectionSetting vertical;
attribute boolean snapToLines; attribute boolean snapToLines;

View File

@ -7,7 +7,7 @@
* http://dev.w3.org/html5/webvtt/#extension-of-the-texttrack-interface-for-region-support * http://dev.w3.org/html5/webvtt/#extension-of-the-texttrack-interface-for-region-support
*/ */
[Constructor, Pref="media.webvtt.enabled"] [Constructor, Func="TextTrackRegion::RegionsEnabled"]
interface VTTRegion { interface VTTRegion {
[SetterThrows] [SetterThrows]
attribute double width; attribute double width;

View File

@ -138,6 +138,7 @@ static const char *sExtensionNames[] = {
"GL_ARB_half_float_pixel", "GL_ARB_half_float_pixel",
"GL_EXT_frag_depth", "GL_EXT_frag_depth",
"GL_OES_compressed_ETC1_RGB8_texture", "GL_OES_compressed_ETC1_RGB8_texture",
"GL_EXT_draw_range_elements",
nullptr nullptr
}; };
@ -1073,6 +1074,20 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
} }
} }
if (IsSupported(GLFeature::draw_range_elements)) {
SymLoadStruct imageSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElementsEXT", "DrawRangeElements", nullptr } },
{ nullptr, { nullptr } },
};
if (!LoadSymbols(&imageSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports draw_range_elements without supplying its functions.");
MarkUnsupported(GLFeature::draw_range_elements);
mSymbols.fDrawRangeElements = nullptr;
}
}
// Load developer symbols, don't fail if we can't find them. // Load developer symbols, don't fail if we can't find them.
SymLoadStruct auxSymbols[] = { SymLoadStruct auxSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } }, { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },

View File

@ -87,6 +87,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature)
depth_texture, depth_texture,
draw_buffers, draw_buffers,
draw_instanced, draw_instanced,
draw_range_elements,
element_index_uint, element_index_uint,
ES2_compatibility, ES2_compatibility,
ES3_compatibility, ES3_compatibility,
@ -419,6 +420,7 @@ public:
ARB_half_float_pixel, ARB_half_float_pixel,
EXT_frag_depth, EXT_frag_depth,
OES_compressed_ETC1_RGB8_texture, OES_compressed_ETC1_RGB8_texture,
EXT_draw_range_elements,
Extensions_Max, Extensions_Max,
Extensions_End Extensions_End
}; };
@ -2228,6 +2230,17 @@ public:
AfterGLDrawCall(); AfterGLDrawCall();
} }
// -----------------------------------------------------------------------------
// Feature draw_range_elements
public:
void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type, const GLvoid* indices)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
AFTER_GL_CALL;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Package XXX_framebuffer_blit // Package XXX_framebuffer_blit

View File

@ -84,6 +84,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End GLContext::Extensions_End
} }
}, },
{
"draw_range_elements",
120, // OpenGL version
300, // OpenGL ES version
{
GLContext::EXT_draw_range_elements,
GLContext::Extensions_End
}
},
{ {
"element_index_uint", "element_index_uint",
200, // OpenGL version 200, // OpenGL version

View File

@ -493,6 +493,10 @@ struct GLContextSymbols
PFNGLOBJECTPTRLABEL fObjectPtrLabel; PFNGLOBJECTPTRLABEL fObjectPtrLabel;
typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABEL) (const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label); typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABEL) (const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label);
PFNGLGETOBJECTPTRLABEL fGetObjectPtrLabel; PFNGLGETOBJECTPTRLABEL fGetObjectPtrLabel;
// draw_range_elements
typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTS) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
PFNGLDRAWRANGEELEMENTS fDrawRangeElements;
}; };
} }

View File

@ -286,19 +286,15 @@ CopyableCanvasLayer::PaintWithOpacity(gfx::DrawTarget* aTarget,
DrawOptions options = DrawOptions(aOpacity, CompositionOp::OP_SOURCE); DrawOptions options = DrawOptions(aOpacity, CompositionOp::OP_SOURCE);
// If content opaque, then save off current operator and set to source.
// This ensures that alpha is not applied even if the source surface
// has an alpha channel
if (GetContentFlags() & CONTENT_OPAQUE) {
options.mCompositionOp = CompositionOp::OP_SOURCE;
}
if (aOperator != CompositionOp::OP_OVER) { if (aOperator != CompositionOp::OP_OVER) {
options.mCompositionOp = aOperator; options.mCompositionOp = aOperator;
} }
// XXX: This needs rewriting for acceptable performance using CoreGraphics.
// Therefore - this ::PaintWithOpacity is currently not used
Rect rect = Rect(0, 0, mBounds.width, mBounds.height); Rect rect = Rect(0, 0, mBounds.width, mBounds.height);
aTarget->FillRect(rect, pat, options); aTarget->FillRect(rect, pat, options);
if (aMaskSurface) { if (aMaskSurface) {
aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), options); aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), options);
} }

View File

@ -79,10 +79,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
bool updated = false; bool updated = false;
{ {
// Restrict drawTarget to a scope so that terminates before Unlock. // Restrict drawTarget to a scope so that terminates before Unlock.
RefPtr<DrawTarget> drawTarget = nsRefPtr<gfxASurface> surface =
mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget(); mBuffer->AsTextureClientSurface()->GetAsSurface();
if (drawTarget) { if (surface) {
aLayer->UpdateTarget(drawTarget); aLayer->DeprecatedUpdateSurface(surface);
updated = true; updated = true;
} }
} }

View File

@ -76,11 +76,12 @@ public:
continue; continue;
} }
if (!child->GetInvalidRegion().IsEmpty()) { ToClientLayer(child)->RenderLayer();
if (!ClientManager()->GetRepeatTransaction() &&
!child->GetInvalidRegion().IsEmpty()) {
child->Mutated(); child->Mutated();
} }
ToClientLayer(child)->RenderLayer();
} }
} }

View File

@ -194,10 +194,10 @@ ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
GetRoot()->ComputeEffectiveTransforms(Matrix4x4()); GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
if (!GetRoot()->GetInvalidRegion().IsEmpty()) { root->RenderLayer();
if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) {
GetRoot()->Mutated(); GetRoot()->Mutated();
} }
root->RenderLayer();
mThebesLayerCallback = nullptr; mThebesLayerCallback = nullptr;
mThebesLayerCallbackData = nullptr; mThebesLayerCallbackData = nullptr;

View File

@ -30,8 +30,8 @@ class nsIWidget;
// IID for the nsITheme interface // IID for the nsITheme interface
// {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822} // {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822}
#define NS_ITHEME_IID \ #define NS_ITHEME_IID \
{ 0x2e49c679, 0x2130, 0x432c, \ { 0x4440b5c7, 0xd8bd, 0x4d9c, \
{ 0x92, 0xcb, 0xd4, 0x8e, 0x9a, 0xe2, 0x34, 0x75 } } { 0x9c, 0x3e, 0xa5, 0xe6, 0x26, 0x81, 0x10, 0xa0 } }
// {D930E29B-6909-44e5-AB4B-AF10D6923705} // {D930E29B-6909-44e5-AB4B-AF10D6923705}
#define NS_THEMERENDERER_CID \ #define NS_THEMERENDERER_CID \
{ 0x9020805b, 0x14a3, 0x4125, \ { 0x9020805b, 0x14a3, 0x4125, \
@ -63,8 +63,7 @@ public:
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect) = 0;
nsIntRegion* aRegionToClear = nullptr) = 0;
/** /**
* Get the computed CSS border for the widget, in pixels. * Get the computed CSS border for the widget, in pixels.

View File

@ -906,6 +906,11 @@ namespace JSC {
return m_buffer.uncheckedSize(); return m_buffer.uncheckedSize();
} }
size_t allocSize() const
{
return m_buffer.allocSize();
}
void ensureSpace(int insnSpace, int constSpace) void ensureSpace(int insnSpace, int constSpace)
{ {
m_buffer.ensureSpace(insnSpace, constSpace); m_buffer.ensureSpace(insnSpace, constSpace);

View File

@ -42,6 +42,7 @@
#include <stdarg.h> #include <stdarg.h>
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "jsopcode.h" #include "jsopcode.h"
#include "jsutil.h"
#include "jit/IonSpewer.h" #include "jit/IonSpewer.h"
#include "js/RootingAPI.h" #include "js/RootingAPI.h"
@ -63,6 +64,7 @@ namespace JSC {
: m_buffer(m_inlineBuffer) : m_buffer(m_inlineBuffer)
, m_capacity(inlineCapacity) , m_capacity(inlineCapacity)
, m_size(0) , m_size(0)
, m_allocSize(0)
, m_oom(false) , m_oom(false)
{ {
} }
@ -143,6 +145,11 @@ namespace JSC {
return m_size; return m_size;
} }
size_t allocSize() const
{
return m_allocSize;
}
bool oom() const bool oom() const
{ {
return m_oom; return m_oom;
@ -159,7 +166,9 @@ namespace JSC {
return 0; return 0;
} }
void* result = allocator->alloc(m_size, poolp, kind); m_allocSize = js::AlignBytes(m_size, sizeof(void *));
void* result = allocator->alloc(m_allocSize, poolp, kind);
if (!result) { if (!result) {
*poolp = NULL; *poolp = NULL;
return 0; return 0;
@ -255,6 +264,7 @@ namespace JSC {
char* m_buffer; char* m_buffer;
size_t m_capacity; size_t m_capacity;
size_t m_size; size_t m_size;
size_t m_allocSize;
bool m_oom; bool m_oom;
}; };

View File

@ -66,38 +66,19 @@ public:
LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator, LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator,
ExecutablePool** poolp, bool* ok, CodeKind codeKind) ExecutablePool** poolp, bool* ok, CodeKind codeKind)
{ {
// LinkBuffer is only used by Yarr. MacroAssemblerCodeRef::release relies on this.
MOZ_ASSERT(codeKind == REGEXP_CODE);
m_codeKind = codeKind; m_codeKind = codeKind;
m_code = executableAllocAndCopy(*masm, executableAllocator, poolp); m_code = executableAllocAndCopy(*masm, executableAllocator, poolp);
m_executablePool = *poolp; m_executablePool = *poolp;
m_size = masm->m_assembler.size(); // must come after call to executableAllocAndCopy()! m_size = masm->m_assembler.size(); // must come after call to executableAllocAndCopy()!
m_allocSize = masm->m_assembler.allocSize();
#ifndef NDEBUG #ifndef NDEBUG
m_completed = false; m_completed = false;
#endif #endif
*ok = !!m_code; *ok = !!m_code;
} }
LinkBuffer(CodeKind kind)
: m_executablePool(NULL)
, m_code(NULL)
, m_size(0)
, m_codeKind(kind)
#ifndef NDEBUG
, m_completed(false)
#endif
{
}
LinkBuffer(uint8_t* ncode, size_t size, CodeKind kind)
: m_executablePool(NULL)
, m_code(ncode)
, m_size(size)
, m_codeKind(kind)
#ifndef NDEBUG
, m_completed(false)
#endif
{
}
~LinkBuffer() ~LinkBuffer()
{ {
ASSERT(!m_executablePool || m_completed); ASSERT(!m_executablePool || m_completed);
@ -183,7 +164,8 @@ public:
{ {
performFinalization(); performFinalization();
return CodeRef(m_code, m_executablePool, m_size); MOZ_ASSERT(m_allocSize >= m_size);
return CodeRef(m_code, m_executablePool, m_allocSize);
} }
CodeLocationLabel finalizeCodeAddendum() CodeLocationLabel finalizeCodeAddendum()
{ {
@ -225,6 +207,7 @@ protected:
ExecutablePool* m_executablePool; ExecutablePool* m_executablePool;
void* m_code; void* m_code;
size_t m_size; size_t m_size;
size_t m_allocSize;
CodeKind m_codeKind; CodeKind m_codeKind;
#ifndef NDEBUG #ifndef NDEBUG
bool m_completed; bool m_completed;

View File

@ -182,14 +182,14 @@ class MacroAssemblerCodeRef {
public: public:
MacroAssemblerCodeRef() MacroAssemblerCodeRef()
: m_executablePool(NULL), : m_executablePool(NULL),
m_size(0) m_allocSize(0)
{ {
} }
MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t size) MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t allocSize)
: m_code(code) : m_code(code)
, m_executablePool(executablePool) , m_executablePool(executablePool)
, m_size(size) , m_allocSize(allocSize)
{ {
} }
@ -201,22 +201,23 @@ public:
#if defined DEBUG && (defined WTF_CPU_X86 || defined WTF_CPU_X86_64) #if defined DEBUG && (defined WTF_CPU_X86 || defined WTF_CPU_X86_64)
void *addr = m_code.executableAddress(); void *addr = m_code.executableAddress();
memset(addr, 0xcc, m_size); memset(addr, 0xcc, m_allocSize);
#endif #endif
m_executablePool->release(); // MacroAssemblerCodeRef is only used by Yarr.
m_executablePool->release(m_allocSize, REGEXP_CODE);
m_executablePool = NULL; m_executablePool = NULL;
} }
MacroAssemblerCodePtr code() const { MacroAssemblerCodePtr code() const {
return m_code; return m_code;
} }
size_t size() const { size_t allocSize() const {
return m_size; return m_allocSize;
} }
MacroAssemblerCodePtr m_code; MacroAssemblerCodePtr m_code;
ExecutablePool* m_executablePool; ExecutablePool* m_executablePool;
size_t m_size; size_t m_allocSize;
}; };
} // namespace JSC } // namespace JSC

View File

@ -440,6 +440,7 @@ public:
}; };
size_t size() const { return m_formatter.size(); } size_t size() const { return m_formatter.size(); }
size_t allocSize() const { return m_formatter.allocSize(); }
unsigned char *buffer() const { return m_formatter.buffer(); } unsigned char *buffer() const { return m_formatter.buffer(); }
bool oom() const { return m_formatter.oom(); } bool oom() const { return m_formatter.oom(); }
@ -3867,6 +3868,7 @@ private:
// Administrative methods: // Administrative methods:
size_t size() const { return m_buffer.size(); } size_t size() const { return m_buffer.size(); }
size_t allocSize() const { return m_buffer.allocSize(); }
unsigned char *buffer() const { return m_buffer.buffer(); } unsigned char *buffer() const { return m_buffer.buffer(); }
bool oom() const { return m_buffer.oom(); } bool oom() const { return m_buffer.oom(); }
bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }

View File

@ -38,6 +38,11 @@ size_t ExecutableAllocator::largeAllocSize = 0;
ExecutablePool::~ExecutablePool() ExecutablePool::~ExecutablePool()
{ {
MOZ_ASSERT(m_ionCodeBytes == 0);
MOZ_ASSERT(m_baselineCodeBytes == 0);
MOZ_ASSERT(m_regexpCodeBytes == 0);
MOZ_ASSERT(m_otherCodeBytes == 0);
m_allocator->releasePoolPages(this); m_allocator->releasePoolPages(this);
} }

View File

@ -85,7 +85,7 @@ namespace JSC {
class ExecutableAllocator; class ExecutableAllocator;
enum CodeKind { ION_CODE, BASELINE_CODE, REGEXP_CODE, OTHER_CODE }; enum CodeKind { ION_CODE = 0, BASELINE_CODE, REGEXP_CODE, OTHER_CODE };
// These are reference-counted. A new one starts with a count of 1. // These are reference-counted. A new one starts with a count of 1.
class ExecutablePool { class ExecutablePool {
@ -130,6 +130,31 @@ public:
if (--m_refCount == 0) if (--m_refCount == 0)
js_delete(this); js_delete(this);
} }
void release(size_t n, CodeKind kind)
{
switch (kind) {
case ION_CODE:
m_ionCodeBytes -= n;
MOZ_ASSERT(m_ionCodeBytes < m_allocation.size); // Shouldn't underflow.
break;
case BASELINE_CODE:
m_baselineCodeBytes -= n;
MOZ_ASSERT(m_baselineCodeBytes < m_allocation.size);
break;
case REGEXP_CODE:
m_regexpCodeBytes -= n;
MOZ_ASSERT(m_regexpCodeBytes < m_allocation.size);
break;
case OTHER_CODE:
m_otherCodeBytes -= n;
MOZ_ASSERT(m_otherCodeBytes < m_allocation.size);
break;
default:
MOZ_ASSUME_UNREACHABLE("bad code kind");
}
release();
}
ExecutablePool(ExecutableAllocator* allocator, Allocation a) ExecutablePool(ExecutableAllocator* allocator, Allocation a)
: m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a), : m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a),
@ -223,10 +248,11 @@ public:
// pool; i.e. alloc() increments the count before returning the object. // pool; i.e. alloc() increments the count before returning the object.
void* alloc(size_t n, ExecutablePool** poolp, CodeKind type) void* alloc(size_t n, ExecutablePool** poolp, CodeKind type)
{ {
// Round 'n' up to a multiple of word size; if all allocations are of // Caller must ensure 'n' is word-size aligned. If all allocations are
// word sized quantities, then all subsequent allocations will be // of word sized quantities, then all subsequent allocations will be
// aligned. // aligned.
n = roundUpAllocationSize(n, sizeof(void*)); JS_ASSERT(roundUpAllocationSize(n, sizeof(void*)) == n);
if (n == OVERSIZE_ALLOCATION) { if (n == OVERSIZE_ALLOCATION) {
*poolp = NULL; *poolp = NULL;
return NULL; return NULL;

View File

@ -615,25 +615,28 @@ JitRuntime::getVMWrapper(const VMFunction &f) const
template <AllowGC allowGC> template <AllowGC allowGC>
JitCode * JitCode *
JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool) JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
JSC::ExecutablePool *pool, JSC::CodeKind kind)
{ {
JitCode *codeObj = js::NewJitCode<allowGC>(cx); JitCode *codeObj = js::NewJitCode<allowGC>(cx);
if (!codeObj) { if (!codeObj) {
pool->release(); pool->release(headerSize + bufferSize, kind);
return nullptr; return nullptr;
} }
new (codeObj) JitCode(code, bufferSize, pool); new (codeObj) JitCode(code, bufferSize, headerSize, pool, kind);
return codeObj; return codeObj;
} }
template template
JitCode * JitCode *
JitCode::New<CanGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); JitCode::New<CanGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
JSC::ExecutablePool *pool, JSC::CodeKind kind);
template template
JitCode * JitCode *
JitCode::New<NoGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); JitCode::New<NoGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
JSC::ExecutablePool *pool, JSC::CodeKind kind);
void void
JitCode::copyFrom(MacroAssembler &masm) JitCode::copyFrom(MacroAssembler &masm)
@ -696,7 +699,7 @@ JitCode::finalize(FreeOp *fop)
// Horrible hack: if we are using perf integration, we don't // Horrible hack: if we are using perf integration, we don't
// want to reuse code addresses, so we just leak the memory instead. // want to reuse code addresses, so we just leak the memory instead.
if (!PerfEnabled()) if (!PerfEnabled())
pool_->release(); pool_->release(headerSize_ + bufferSize_, JSC::CodeKind(kind_));
pool_ = nullptr; pool_ = nullptr;
} }
} }

View File

@ -14,6 +14,7 @@
#include "jsinfer.h" #include "jsinfer.h"
#include "jstypes.h" #include "jstypes.h"
#include "assembler/jit/ExecutableAllocator.h"
#include "gc/Heap.h" #include "gc/Heap.h"
#include "jit/IonOptimizationLevels.h" #include "jit/IonOptimizationLevels.h"
#include "jit/IonTypes.h" #include "jit/IonTypes.h"
@ -37,13 +38,15 @@ class JitCode : public gc::BarrieredCell<JitCode>
protected: protected:
uint8_t *code_; uint8_t *code_;
JSC::ExecutablePool *pool_; JSC::ExecutablePool *pool_;
uint32_t bufferSize_; // Total buffer size. uint32_t bufferSize_; // Total buffer size. Does not include headerSize_.
uint32_t insnSize_; // Instruction stream size. uint32_t insnSize_; // Instruction stream size.
uint32_t dataSize_; // Size of the read-only data area. uint32_t dataSize_; // Size of the read-only data area.
uint32_t jumpRelocTableBytes_; // Size of the jump relocation table. uint32_t jumpRelocTableBytes_; // Size of the jump relocation table.
uint32_t dataRelocTableBytes_; // Size of the data relocation table. uint32_t dataRelocTableBytes_; // Size of the data relocation table.
uint32_t preBarrierTableBytes_; // Size of the prebarrier table. uint32_t preBarrierTableBytes_; // Size of the prebarrier table.
bool invalidated_; // Whether the code object has been invalidated. uint8_t headerSize_ : 5; // Number of bytes allocated before codeStart.
uint8_t kind_ : 3; // JSC::CodeKind, for the memory reporters.
bool invalidated_ : 1; // Whether the code object has been invalidated.
// This is necessary to prevent GC tracing. // This is necessary to prevent GC tracing.
#if JS_BITS_PER_WORD == 32 #if JS_BITS_PER_WORD == 32
@ -55,7 +58,8 @@ class JitCode : public gc::BarrieredCell<JitCode>
: code_(nullptr), : code_(nullptr),
pool_(nullptr) pool_(nullptr)
{ } { }
JitCode(uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool) JitCode(uint8_t *code, uint32_t bufferSize, uint32_t headerSize, JSC::ExecutablePool *pool,
JSC::CodeKind kind)
: code_(code), : code_(code),
pool_(pool), pool_(pool),
bufferSize_(bufferSize), bufferSize_(bufferSize),
@ -64,8 +68,13 @@ class JitCode : public gc::BarrieredCell<JitCode>
jumpRelocTableBytes_(0), jumpRelocTableBytes_(0),
dataRelocTableBytes_(0), dataRelocTableBytes_(0),
preBarrierTableBytes_(0), preBarrierTableBytes_(0),
headerSize_(headerSize),
kind_(kind),
invalidated_(false) invalidated_(false)
{ } {
MOZ_ASSERT(JSC::CodeKind(kind_) == kind);
MOZ_ASSERT(headerSize_ == headerSize);
}
uint32_t dataOffset() const { uint32_t dataOffset() const {
return insnSize_; return insnSize_;
@ -126,7 +135,8 @@ class JitCode : public gc::BarrieredCell<JitCode>
// object can be allocated, nullptr is returned. On failure, |pool| is // object can be allocated, nullptr is returned. On failure, |pool| is
// automatically released, so the code may be freed. // automatically released, so the code may be freed.
template <AllowGC allowGC> template <AllowGC allowGC>
static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
JSC::ExecutablePool *pool, JSC::CodeKind kind);
public: public:
static inline ThingRootKind rootKind() { return THING_ROOT_JIT_CODE; } static inline ThingRootKind rootKind() { return THING_ROOT_JIT_CODE; }

View File

@ -44,6 +44,9 @@ class Linker
if (bytesNeeded >= MAX_BUFFER_SIZE) if (bytesNeeded >= MAX_BUFFER_SIZE)
return fail(cx); return fail(cx);
// ExecutableAllocator requires bytesNeeded to be word-size aligned.
bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *));
uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind); uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind);
if (!result) if (!result)
return fail(cx); return fail(cx);
@ -54,8 +57,8 @@ class Linker
// Bump the code up to a nice alignment. // Bump the code up to a nice alignment.
codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment); codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment);
uint32_t headerSize = codeStart - result; uint32_t headerSize = codeStart - result;
JitCode *code = JitCode::New<allowGC>(cx, codeStart, JitCode *code = JitCode::New<allowGC>(cx, codeStart, bytesNeeded - headerSize,
bytesNeeded - headerSize, pool); headerSize, pool, kind);
if (!code) if (!code)
return nullptr; return nullptr;
if (masm.oom()) if (masm.oom())

View File

@ -2549,7 +2549,7 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
* (FIXME: remove this dependency on the exact identity of the parent, * (FIXME: remove this dependency on the exact identity of the parent,
* perhaps as part of bug 638316.) * perhaps as part of bug 638316.)
*/ */
RootedFunction fun(cx, NewFunction(cx, NullPtr(), constructor, nargs, RootedFunction fun(cx, NewFunction(cx, js::NullPtr(), constructor, nargs,
JSFunction::NATIVE_CTOR, obj, atom, ctorKind)); JSFunction::NATIVE_CTOR, obj, atom, ctorKind));
if (!fun) if (!fun)
goto bad; goto bad;

View File

@ -82,16 +82,16 @@ public:
bool isFallBack() { return m_needFallBack; } bool isFallBack() { return m_needFallBack; }
#ifdef YARR_8BIT_CHAR_SUPPORT #ifdef YARR_8BIT_CHAR_SUPPORT
bool has8BitCode() const { return m_ref8.size(); } bool has8BitCode() const { return m_ref8.allocSize(); }
void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; } void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; }
bool has8BitCodeMatchOnly() const { return m_matchOnly8.size(); } bool has8BitCodeMatchOnly() const { return m_matchOnly8.allocSize(); }
void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; } void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
#endif #endif
bool has16BitCode() const { return m_ref16.size(); } bool has16BitCode() const { return m_ref16.allocSize(); }
void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; } void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; }
bool has16BitCodeMatchOnly() const { return m_matchOnly16.size(); } bool has16BitCodeMatchOnly() const { return m_matchOnly16.allocSize(); }
void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; } void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
#if YARR_8BIT_CHAR_SUPPORT #if YARR_8BIT_CHAR_SUPPORT

View File

@ -3761,9 +3761,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext(); nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
rc->Init(presContext->DeviceContext(), aContext); rc->Init(presContext->DeviceContext(), aContext);
nsIntRegion temp = builder->GetRegionToClear();
builder->ResetRegionToClear();
if (shouldDrawRectsSeparately) { if (shouldDrawRectsSeparately) {
nsIntRegionRectIterator it(aRegionToDraw); nsIntRegionRectIterator it(aRegionToDraw);
while (const nsIntRect* iterRect = it.Next()) { while (const nsIntRect* iterRect = it.Next()) {
@ -3805,12 +3802,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
if (!aRegionToInvalidate.IsEmpty()) { if (!aRegionToInvalidate.IsEmpty()) {
aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds()); aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds());
} }
if (!builder->GetRegionToClear().IsEmpty()) {
aLayer->Manager()->SetRegionToClear(builder->GetRegionToClear());
}
builder->ResetRegionToClear();
builder->AddRegionToClear(temp);
} }
bool bool

View File

@ -854,7 +854,8 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode,
return NS_OK; return NS_OK;
} }
nsresult nsCaret::CheckCaretDrawingState() void
nsCaret::CheckCaretDrawingState()
{ {
if (mDrawn) { if (mDrawn) {
// The caret is drawn; if it shouldn't be, erase it. // The caret is drawn; if it shouldn't be, erase it.
@ -867,7 +868,6 @@ nsresult nsCaret::CheckCaretDrawingState()
if (mPendingDraw && (mVisible && MustDrawCaret(true))) if (mPendingDraw && (mVisible && MustDrawCaret(true)))
DrawCaret(true); DrawCaret(true);
} }
return NS_OK;
} }
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------

View File

@ -163,7 +163,7 @@ class nsCaret : public nsISelectionListener
nsIFrame** aReturnFrame, nsIFrame** aReturnFrame,
int32_t* aReturnOffset); int32_t* aReturnOffset);
NS_IMETHOD CheckCaretDrawingState(); void CheckCaretDrawingState();
protected: protected:

View File

@ -2358,6 +2358,7 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil
case NS_THEME_WINDOW_TITLEBAR: case NS_THEME_WINDOW_TITLEBAR:
case NS_THEME_WINDOW_BUTTON_BOX: case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
RegisterThemeGeometry(aBuilder, aFrame); RegisterThemeGeometry(aBuilder, aFrame);
break; break;
case NS_THEME_WIN_BORDERLESS_GLASS: case NS_THEME_WIN_BORDERLESS_GLASS:
@ -2445,11 +2446,7 @@ nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance, theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance,
&drawing); &drawing);
drawing.IntersectRect(drawing, aBounds); drawing.IntersectRect(drawing, aBounds);
nsIntRegion clear; theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing);
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing, &clear);
MOZ_ASSERT(clear.IsEmpty() || ReferenceFrame() == aBuilder->RootReferenceFrame(),
"Can't add to clear region if we're transformed!");
aBuilder->AddRegionToClear(clear);
} }
bool nsDisplayThemedBackground::IsWindowActive() bool nsDisplayThemedBackground::IsWindowActive()

View File

@ -641,10 +641,6 @@ public:
DisplayListClipState& ClipState() { return mClipState; } DisplayListClipState& ClipState() { return mClipState; }
void AddRegionToClear(const nsIntRegion& aRegion) { mRegionToClear.Or(mRegionToClear, aRegion); }
const nsIntRegion& GetRegionToClear() { return mRegionToClear; }
void ResetRegionToClear() { mRegionToClear.SetEmpty(); }
private: private:
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
const nsRect& aDirtyRect); const nsRect& aDirtyRect);
@ -678,8 +674,6 @@ private:
const nsIFrame* mCachedReferenceFrame; const nsIFrame* mCachedReferenceFrame;
nsPoint mCachedOffset; nsPoint mCachedOffset;
nsRegion mExcludedGlassRegion; nsRegion mExcludedGlassRegion;
// Area of the window (in pixels) to clear so the OS can draw them.
nsIntRegion mRegionToClear;
// The display item for the Windows window glass background, if any // The display item for the Windows window glass background, if any
nsDisplayItem* mGlassDisplayItem; nsDisplayItem* mGlassDisplayItem;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy; nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;

View File

@ -294,6 +294,7 @@ pref("media.tabstreaming.time_per_frame", 40);
// TextTrack support // TextTrack support
pref("media.webvtt.enabled", true); pref("media.webvtt.enabled", true);
pref("media.webvtt.regions.enabled", false);
// Whether to enable MediaSource support // Whether to enable MediaSource support
pref("media.mediasource.enabled", false); pref("media.mediasource.enabled", false);

View File

@ -34,8 +34,7 @@ public:
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect);
nsIntRegion* aRegionToClear);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,

View File

@ -2080,8 +2080,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect)
nsIntRegion* aRegionToClear)
{ {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;

View File

@ -752,8 +752,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect)
nsIntRegion* aRegionToClear)
{ {
GtkWidgetState state; GtkWidgetState state;
GtkThemeWidgetType gtkWidgetType; GtkThemeWidgetType gtkWidgetType;

View File

@ -24,8 +24,7 @@ public:
NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext, NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame, uint8_t aWidgetType, nsIFrame* aFrame, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect);
nsIntRegion* aRegionToClear);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType, nsIntMargin* aResult); uint8_t aWidgetType, nsIntMargin* aResult);

View File

@ -1536,8 +1536,7 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect)
nsIntRegion* aRegionToClear)
{ {
HANDLE theme = GetTheme(aWidgetType); HANDLE theme = GetTheme(aWidgetType);
if (!theme) if (!theme)
@ -1568,6 +1567,10 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
case NS_THEME_WIN_BORDERLESS_GLASS: case NS_THEME_WIN_BORDERLESS_GLASS:
// Nothing to draw, this is the glass background. // Nothing to draw, this is the glass background.
return NS_OK; return NS_OK;
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
// We handle these through nsIWidget::UpdateThemeGeometries
return NS_OK;
break; break;
} }
} }
@ -1900,20 +1903,6 @@ RENDER_AGAIN:
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect); DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect);
} }
} }
else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
nsUXThemeData::CheckForCompositor())
{
// The caption buttons are drawn by the DWM, we just need to clear the area where they
// are because we might have drawn something above them (like a background-image).
NS_ASSERTION(aRegionToClear, "Must have a clear region to set!");
if (aRegionToClear) {
// Create a rounded rectangle to follow the buttons' look.
*aRegionToClear = nsIntRect(dr.X(), dr.Y(), dr.Width(), dr.Height() - 2.0);
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 1.0, dr.YMost() - 2.0, dr.Width() - 1.0, 1.0));
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 2.0, dr.YMost() - 1.0, dr.Width() - 3.0, 1.0));
}
}
nativeDrawing.EndNativeDrawing(); nativeDrawing.EndNativeDrawing();

View File

@ -31,8 +31,7 @@ public:
nsIFrame* aFrame, nsIFrame* aFrame,
uint8_t aWidgetType, uint8_t aWidgetType,
const nsRect& aRect, const nsRect& aRect,
const nsRect& aDirtyRect, const nsRect& aDirtyRect);
nsIntRegion* aRegionToClear);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame, nsIFrame* aFrame,

View File

@ -127,6 +127,7 @@
#include "nsToolkitCompsCID.h" #include "nsToolkitCompsCID.h"
#include "nsIAppStartup.h" #include "nsIAppStartup.h"
#include "mozilla/WindowsVersion.h" #include "mozilla/WindowsVersion.h"
#include "nsThemeConstants.h"
#ifdef MOZ_ENABLE_D3D9_LAYER #ifdef MOZ_ENABLE_D3D9_LAYER
#include "LayerManagerD3D9.h" #include "LayerManagerD3D9.h"
@ -3556,6 +3557,28 @@ nsWindow::EndRemoteDrawing()
mCompositeDC = nullptr; mCompositeDC = nullptr;
} }
void
nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
{
nsIntRegion clearRegion;
for (size_t i = 0; i < aThemeGeometries.Length(); i++) {
if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
nsUXThemeData::CheckForCompositor())
{
nsIntRect bounds = aThemeGeometries[i].mRect;
clearRegion = nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0);
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 1.0, bounds.YMost() - 2.0, bounds.Width() - 1.0, 1.0));
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 2.0, bounds.YMost() - 1.0, bounds.Width() - 3.0, 1.0));
}
}
nsRefPtr<LayerManager> layerManager = GetLayerManager();
if (layerManager) {
layerManager->SetRegionToClear(clearRegion);
}
}
/************************************************************** /**************************************************************
************************************************************** **************************************************************
** **

View File

@ -196,6 +196,8 @@ public:
mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE; mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE;
virtual void EndRemoteDrawing() MOZ_OVERRIDE; virtual void EndRemoteDrawing() MOZ_OVERRIDE;
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) MOZ_OVERRIDE;
/** /**
* Event helpers * Event helpers
*/ */