merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-11-15 12:26:41 +01:00
Родитель 2a84d7eb81 1214667549
Коммит 8cfa5253e8
236 изменённых файлов: 7828 добавлений и 4783 удалений

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

@ -463,11 +463,6 @@ HTMLTextFieldAccessible::GetEditor() const
if (!editableElt)
return nullptr;
// nsGenericHTMLElement::GetEditor has a security check.
// Make sure we're not restricted by the permissions of
// whatever script is currently running.
mozilla::dom::AutoNoJSAPI nojsapi;
nsCOMPtr<nsIEditor> editor;
editableElt->GetEditor(getter_AddRefs(editor));

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

@ -639,6 +639,12 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
font-weight: bold;
}
.bookmark-item > label {
/* ensure we use the direction of the bookmarks label instead of the
* browser locale */
unicode-bidi: plaintext;
}
toolbarbutton.bookmark-item {
max-width: 13em;
}

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

@ -24,6 +24,12 @@ function test() {
function zoomTab1() {
Task.spawn(function* () {
is(gBrowser.selectedTab, gTab1, "Tab 1 is selected");
// Reset zoom level if we run this test > 1 time in same browser session.
var level1 = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1));
if (level1 > 1)
FullZoom.reduce();
FullZoomHelper.zoomTest(gTab1, 1, "Initial zoom of tab 1 should be 1");
FullZoomHelper.zoomTest(gTab2, 1, "Initial zoom of tab 2 should be 1");

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

@ -7,6 +7,9 @@ Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
var Sanitizer = tempScope.Sanitizer;
add_task(function*() {
// getLoginSavingEnabled always returns false if password capture is disabled.
yield SpecialPowers.pushPrefEnv({"set": [["signon.rememberSignons", true]]});
var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
// Add a disabled host
@ -36,4 +39,6 @@ add_task(function*() {
// Make sure it's gone
is(pwmgr.getLoginSavingEnabled("http://example.com"), true,
"example.com should be enabled for password saving again now that we've cleared.");
yield SpecialPowers.popPrefEnv();
});

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

@ -2,10 +2,10 @@
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function* openPanel(extension, win = window) {
function* openPanel(extension, win = window, awaitLoad = false) {
clickBrowserAction(extension, win);
return yield awaitExtensionPanel(extension, win, false);
return yield awaitExtensionPanel(extension, win, awaitLoad);
}
add_task(function* testBrowserActionPopupResize() {
@ -113,7 +113,7 @@ function* testPopupSize(standardsMode, browserWin = window, arrowSide = "top") {
if (arrowSide == "top") {
// Test the standalone panel for a toolbar button.
let browser = yield openPanel(extension, browserWin);
let browser = yield openPanel(extension, browserWin, true);
let dims = yield promiseContentDimensions(browser);

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

@ -6,6 +6,12 @@ tree[type="places"] {
-moz-binding: url("chrome://browser/content/places/tree.xml#places-tree");
}
tree[type="places"] > treechildren::-moz-tree-cell {
/* ensure we use the direction of the website title / url instead of the
* browser locale */
unicode-bidi: plaintext;
}
.toolbar-drop-indicator {
position: relative;
z-index: 1;

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

@ -42,7 +42,7 @@
onpopupshowing="return window.top.BookmarksEventHandler.fillInBHTooltip(document, event)">
<vbox id="bhTooltipTextBox" flex="1">
<label id="bhtTitleText" class="tooltip-label" />
<label id="bhtUrlText" crop="center" class="tooltip-label" />
<label id="bhtUrlText" crop="center" class="tooltip-label uri-element" />
</vbox>
</tooltip>

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

@ -383,6 +383,16 @@ description#identity-popup-content-verifier,
50% { opacity: 0; }
}
.identity-popup-permission-label,
.identity-popup-permission-state-label {
/* We need to align the action buttons and permission icons with the text.
This is tricky because the icon height is defined in pixels, while the
font height can vary with platform and system settings, and at least on
Windows the default font metrics reserve more extra space for accents.
This value is a good compromise for different platforms and font sizes. */
margin-top: -0.1em;
}
.identity-popup-permission-label {
margin-inline-start: 1em;
}

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

@ -4,7 +4,7 @@
# Bug 1200740 - ASan crash due to child process function interceptions
# Sandbox executes some of its code before the ASan RTL gets initialized and
# maps shadow memory. As a result, instrmented code tries to access unavailable
# maps shadow memory. As a result, instrumented code tries to access unavailable
# shadow memory and faults.
fun:*TargetNtSetInformationThread@20
fun:*TargetNtOpenThreadToken@20
@ -24,3 +24,4 @@ src:*process_thread_interception.cc
src:*registry_interception.cc
src:*sandbox_nt_util.cc
src:*sync_interception.cc
src:*interceptors_64.cc

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

@ -15,6 +15,9 @@ thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Shader Editor is " +
const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/main");
// Bug 1277805: Too slow for debug runs
requestLongerTimeout(2);
/**
* Bug 979536: Ensure fronts are destroyed after toolbox close.
*

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

@ -11843,7 +11843,20 @@ void
nsGlobalWindow::Suspend()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
// We can only safely suspend windows that are the current inner window. If
// its not the current inner, then we are in one of two different cases.
// Either we are in the bfcache or we are doomed window that is going away.
// When a window becomes inactive we purposely avoid placing already suspended
// windows into the bfcache. It only expects windows suspended due to the
// Freeze() method which occurs while the window is still the current inner.
// So we must not call Suspend() on bfcache windows at this point or this
// invariant will be broken. If the window is doomed there is no point in
// suspending it since it will soon be gone.
if (!AsInner()->IsCurrentInnerWindow()) {
return;
}
// All children are also suspended. This ensure mSuspendDepth is
// set properly and the timers are properly canceled for each child.
@ -11891,7 +11904,17 @@ void
nsGlobalWindow::Resume()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
// We can only safely resume a window if its the current inner window. If
// its not the current inner, then we are in one of two different cases.
// Either we are in the bfcache or we are doomed window that is going away.
// If a window is suspended when it becomes inactive we purposely do not
// put it in the bfcache, so Resume should never be needed in that case.
// If the window is doomed then there is no point in resuming it.
if (!AsInner()->IsCurrentInnerWindow()) {
return;
}
// Resume all children. This restores timers recursively canceled
// in Suspend() and ensures all children have the correct mSuspendDepth.
@ -11988,7 +12011,6 @@ void
nsGlobalWindow::Freeze()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInnerWindow());
Suspend();
FreezeInternal();
}
@ -11997,7 +12019,9 @@ void
nsGlobalWindow::FreezeInternal()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsSuspended());
MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(AsInner()->IsCurrentInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsSuspended());
CallOnChildren(&nsGlobalWindow::FreezeInternal);
@ -12033,7 +12057,6 @@ void
nsGlobalWindow::Thaw()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInnerWindow());
ThawInternal();
Resume();
}
@ -12042,7 +12065,9 @@ void
nsGlobalWindow::ThawInternal()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsSuspended());
MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(AsInner()->IsCurrentInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsSuspended());
CallOnChildren(&nsGlobalWindow::ThawInternal);
@ -12099,6 +12124,7 @@ nsGlobalWindow::SyncStateFromParentWindow()
// This method should only be called on an inner window that has been
// assigned to an outer window already.
MOZ_ASSERT(IsInnerWindow());
MOZ_ASSERT(AsInner()->IsCurrentInnerWindow());
nsPIDOMWindowOuter* outer = GetOuterWindow();
MOZ_ASSERT(outer);
@ -12142,6 +12168,8 @@ void
nsGlobalWindow::CallOnChildren(Method aMethod)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInnerWindow());
MOZ_ASSERT(AsInner()->IsCurrentInnerWindow());
nsCOMPtr<nsIDocShell> docShell = GetDocShell();
if (!docShell) {

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

@ -1092,13 +1092,13 @@ DOMInterfaces = {
'headerFile': 'WebGLExtensions.h'
},
'WEBGL_compressed_texture_etc1': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureETC1',
'WEBGL_compressed_texture_etc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
'headerFile': 'WebGLExtensions.h'
},
'WEBGL_compressed_texture_es3': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
'WEBGL_compressed_texture_etc1': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureETC1',
'headerFile': 'WebGLExtensions.h'
},
@ -1280,11 +1280,6 @@ DOMInterfaces = {
'headerFile': 'WebGLTexture.h'
},
'WebGLTimerQueryEXT': {
'nativeType': 'mozilla::WebGLTimerQuery',
'headerFile': 'WebGLTimerQuery.h'
},
'WebGLTransformFeedback': {
'nativeType': 'mozilla::WebGLTransformFeedback',
'headerFile': 'WebGLTransformFeedback.h'

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

@ -38,12 +38,6 @@ WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
return dom::WebGLRenderingContextBinding::Wrap(cx, this, givenProto);
}
bool
WebGL1Context::ValidateQueryTarget(GLenum target, const char* info)
{
return false;
}
} // namespace mozilla
nsresult

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

@ -36,7 +36,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
uint32_t* alignment,
const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;
};

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

@ -302,18 +302,6 @@ public:
void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil);
// -------------------------------------------------------------------------
// Query Objects - WebGL2ContextQueries.cpp
already_AddRefed<WebGLQuery> CreateQuery();
void DeleteQuery(WebGLQuery* query);
bool IsQuery(WebGLQuery* query);
void BeginQuery(GLenum target, WebGLQuery* query);
void EndQuery(GLenum target);
already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
void GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS::MutableHandleValue retval);
// -------------------------------------------------------------------------
// Sampler Objects - WebGL2ContextSamplers.cpp
@ -410,7 +398,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
uint32_t* alignment,
const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;
};

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

@ -22,58 +22,35 @@ namespace mozilla {
* implementation-dependent cases.
*/
static const char*
GetQueryTargetEnumString(GLenum target)
WebGLRefPtr<WebGLQuery>*
WebGLContext::ValidateQuerySlotByTarget(const char* funcName, GLenum target)
{
switch (target)
{
case LOCAL_GL_ANY_SAMPLES_PASSED:
return "ANY_SAMPLES_PASSED";
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return "ANY_SAMPLES_PASSED_CONSERVATIVE";
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN";
default:
break;
if (IsWebGL2()) {
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return &mQuerySlot_SamplesPassed;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return &mQuerySlot_TFPrimsWritten;
default:
break;
}
}
MOZ_ASSERT(false, "Unknown query `target`.");
return "UNKNOWN_QUERY_TARGET";
}
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
switch (target) {
case LOCAL_GL_TIME_ELAPSED_EXT:
return &mQuerySlot_TimeElapsed;
static inline GLenum
SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target)
{
MOZ_ASSERT(target == LOCAL_GL_ANY_SAMPLES_PASSED ||
target == LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
"unknown occlusion query target");
if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean)) {
return target;
} else if (gl->IsSupported(gl::GLFeature::occlusion_query2)) {
return LOCAL_GL_ANY_SAMPLES_PASSED;
default:
break;
}
}
return LOCAL_GL_SAMPLES_PASSED;
}
WebGLRefPtr<WebGLQuery>&
WebGLContext::GetQuerySlotByTarget(GLenum target)
{
/* This function assumes that target has been validated for either
* WebGL1 or WebGL2.
*/
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return mActiveOcclusionQuery;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return mActiveTransformFeedbackQuery;
default:
MOZ_CRASH("GFX: Should not get here.");
}
ErrorInvalidEnum("%s: Bad `target`.", funcName);
return nullptr;
}
@ -81,329 +58,193 @@ WebGLContext::GetQuerySlotByTarget(GLenum target)
// Query Objects
already_AddRefed<WebGLQuery>
WebGL2Context::CreateQuery()
WebGLContext::CreateQuery(const char* funcName)
{
if (!funcName) {
funcName = "createQuery";
}
if (IsContextLost())
return nullptr;
if (mActiveOcclusionQuery && !gl->IsGLES()) {
/* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
*
* Calling either GenQueriesARB or DeleteQueriesARB while any query of
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("createQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when creating a query object while"
" one other is active.");
/*
* We *need* to lock webgl2 to GL>=3.0 on desktop, but we don't have a
* good mechanism to do this yet. See bug 898404.
*/
}
RefPtr<WebGLQuery> globj = new WebGLQuery(this);
return globj.forget();
}
void
WebGL2Context::DeleteQuery(WebGLQuery* query)
WebGLContext::DeleteQuery(WebGLQuery* query, const char* funcName)
{
if (!funcName) {
funcName = "deleteQuery";
}
if (IsContextLost())
return;
if (!query)
return;
if (query->IsDeleted())
if (!ValidateObjectAllowDeleted(funcName, query))
return;
if (query->IsActive())
EndQuery(query->mType);
if (mActiveOcclusionQuery && !gl->IsGLES()) {
/* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
*
* Calling either GenQueriesARB or DeleteQueriesARB while any query of
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("deleteQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when deleting a query object while"
" one other is active.");
}
query->RequestDelete();
query->DeleteQuery();
}
bool
WebGL2Context::IsQuery(WebGLQuery* query)
WebGLContext::IsQuery(const WebGLQuery* query, const char* funcName)
{
if (!funcName) {
funcName = "isQuery";
}
if (IsContextLost())
return false;
if (!query)
return false;
return (ValidateObjectAllowDeleted("isQuery", query) &&
!query->IsDeleted() &&
query->HasEverBeenActive());
}
void
WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query)
{
if (IsContextLost())
return;
if (!ValidateQueryTarget(target, "beginQuery"))
return;
if (!query) {
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT sets the active query object name for the query
* type given by <target> to <id>. If BeginQueryEXT is called with
* an <id> of zero, if the active query object name for <target> is
* non-zero (for the targets ANY_SAMPLES_PASSED_EXT and
* ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if the active query for
* either target is non-zero), if <id> is the name of an existing
* query object whose type does not match <target>, or if <id> is
* the active query object name for any query type, the error
* INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("beginQuery: Query should not be null.");
return;
}
if (query->IsDeleted()) {
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT fails and an INVALID_OPERATION error is generated
* if <id> is not a name returned from a previous call to
* GenQueriesEXT, or if such a name has since been deleted with
* DeleteQueriesEXT.
*/
ErrorInvalidOperation("beginQuery: Query has been deleted.");
return;
}
if (query->HasEverBeenActive() &&
query->mType != target)
{
ErrorInvalidOperation("beginQuery: Target doesn't match with the query"
" type.");
return;
}
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
WebGLQuery* activeQuery = querySlot.get();
if (activeQuery)
return ErrorInvalidOperation("beginQuery: An other query already active.");
if (!query->HasEverBeenActive())
query->mType = target;
MakeContextCurrent();
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
gl->fBeginQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
query->mGLName);
} else {
gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target),
query->mGLName);
}
UpdateBoundQuery(target, query);
}
void
WebGL2Context::EndQuery(GLenum target)
{
if (IsContextLost())
return;
if (!ValidateQueryTarget(target, "endQuery"))
return;
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
WebGLQuery* activeQuery = querySlot.get();
if (!activeQuery || target != activeQuery->mType)
{
/* From GLES's EXT_occlusion_query_boolean:
* marks the end of the sequence of commands to be tracked for the
* query type given by <target>. The active query object for
* <target> is updated to indicate that query results are not
* available, and the active query object name for <target> is reset
* to zero. When the commands issued prior to EndQueryEXT have
* completed and a final query result is available, the query object
* active when EndQueryEXT is called is updated by the GL. The query
* object is updated to indicate that the query results are
* available and to contain the query result. If the active query
* object name for <target> is zero when EndQueryEXT is called, the
* error INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("endQuery: There is no active query of type %s.",
GetQueryTargetEnumString(target));
return;
}
MakeContextCurrent();
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
gl->fEndQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
} else {
gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target));
}
UpdateBoundQuery(target, nullptr);
NS_DispatchToCurrentThread(new WebGLQuery::AvailableRunnable(activeQuery));
}
already_AddRefed<WebGLQuery>
WebGL2Context::GetQuery(GLenum target, GLenum pname)
{
if (IsContextLost())
return nullptr;
if (!ValidateQueryTarget(target, "getQuery"))
return nullptr;
if (pname != LOCAL_GL_CURRENT_QUERY) {
/* OpenGL ES 3.0 spec 6.1.7:
* pname must be CURRENT_QUERY.
*/
ErrorInvalidEnum("getQuery: `pname` must be CURRENT_QUERY.");
return nullptr;
}
WebGLRefPtr<WebGLQuery>& targetSlot = GetQuerySlotByTarget(target);
RefPtr<WebGLQuery> tmp = targetSlot.get();
if (tmp && tmp->mType != target) {
// Query in slot doesn't match target
return nullptr;
}
return tmp.forget();
}
static bool
ValidateQueryEnum(WebGLContext* webgl, GLenum pname, const char* info)
{
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
return true;
default:
webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname));
if (!ValidateObjectAllowDeleted("isQuery", query))
return false;
}
return query->IsQuery();
}
void
WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval)
WebGLContext::BeginQuery(GLenum target, WebGLQuery* query, const char* funcName)
{
retval.set(JS::NullValue());
if (!funcName) {
funcName = "beginQuery";
}
if (IsContextLost())
return;
if (!ValidateQueryEnum(this, pname, "getQueryParameter"))
if (!ValidateObjectAllowDeleted(funcName, query))
return;
if (!query) {
/* OpenGL ES 3.0 spec 6.1.7 (spec getQueryObject 1):
* If id is not the name of a query object, or if the query object
* named by id is currently active, then an INVALID_OPERATION error
* is generated. pname must be QUERY_RESULT or
* QUERY_RESULT_AVAILABLE.
*/
ErrorInvalidOperation("getQueryObject: `query` should not be null.");
if (query->IsDeleted())
return ErrorInvalidOperation("%s: Cannot begin a deleted query.", funcName);
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot)
return;
if (*slot)
return ErrorInvalidOperation("%s: Query target already active.", funcName);
////
query->BeginQuery(target, *slot);
}
void
WebGLContext::EndQuery(GLenum target, const char* funcName)
{
if (!funcName) {
funcName = "endQuery";
}
if (query->IsDeleted()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: `query` has been deleted.");
if (IsContextLost())
return;
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot)
return;
const auto& query = *slot;
if (!query)
return ErrorInvalidOperation("%s: Query target not active.", funcName);
query->EndQuery();
}
void
WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName)
{
if (!funcName) {
funcName = "getQuery";
}
if (query->IsActive()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: `query` is active.");
retval.setNull();
if (IsContextLost())
return;
}
if (!query->HasEverBeenActive()) {
/* See (spec getQueryObject 1)
* If this instance of WebGLQuery has never been active before, that
* mean that query->mGLName is not a query object yet.
*/
ErrorInvalidOperation("getQueryObject: `query` has never been active.");
return;
}
switch (pname) {
case LOCAL_GL_CURRENT_QUERY_EXT:
{
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query) &&
target == LOCAL_GL_TIMESTAMP)
{
// Doesn't seem illegal to ask about, but is always null.
// TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate
// INVALID_ENUM.
return;
}
// We must wait for an event loop before the query can be available
if (!query->mCanBeAvailable && !gfxPrefs::WebGLImmediateQueries()) {
if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
retval.set(JS::BooleanValue(false));
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot || !*slot)
return;
const auto& query = *slot;
if (target != query->Target())
return;
JS::Rooted<JS::Value> v(cx);
dom::GetOrCreateDOMReflector(cx, slot->get(), &v);
retval.set(v);
}
return;
}
MakeContextCurrent();
GLuint returned = 0;
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
gl->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT_AVAILABLE, &returned);
retval.set(JS::BooleanValue(returned != 0));
return;
case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query))
break;
case LOCAL_GL_QUERY_RESULT:
gl->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT, &returned);
if (query->mType == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
retval.set(JS::NumberValue(returned));
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT)
{
ErrorInvalidEnum("%s: Bad pname for target.", funcName);
return;
}
/*
* test (returned != 0) is important because ARB_occlusion_query on desktop drivers
* return the number of samples drawed when the OpenGL ES extension
* ARB_occlusion_query_boolean return only a boolean if a sample has been drawed.
*/
retval.set(JS::BooleanValue(returned != 0));
{
GLint bits = 0;
gl->fGetQueryiv(target, pname, &bits);
if (!Has64BitTimestamps() && bits > 32) {
bits = 32;
}
retval.set(JS::Int32Value(bits));
}
return;
default:
break;
}
ErrorInvalidEnum("getQueryObject: `pname` must be QUERY_RESULT{_AVAILABLE}.");
ErrorInvalidEnum("%s: Bad pname.", funcName);
return;
}
void
WebGL2Context::UpdateBoundQuery(GLenum target, WebGLQuery* query)
WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName)
{
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
querySlot = query;
}
bool
WebGL2Context::ValidateQueryTarget(GLenum target, const char* info)
{
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return true;
default:
ErrorInvalidEnumInfo(info, target);
return false;
if (!funcName) {
funcName = "getQueryParameter";
}
retval.setNull();
if (IsContextLost())
return;
if (!ValidateObjectAllowDeleted(funcName, query))
return;
if (query->IsDeleted())
return ErrorInvalidOperation("%s: Query must not be deleted.", funcName);
query->GetQueryParameter(pname, retval);
}
} // namespace mozilla

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

@ -71,7 +71,6 @@
#include "WebGLSampler.h"
#include "WebGLShader.h"
#include "WebGLSync.h"
#include "WebGLTimerQuery.h"
#include "WebGLTransformFeedback.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
@ -252,13 +251,16 @@ WebGLContext::DestroyResourcesAndContext()
mActiveProgramLinkInfo = nullptr;
mBoundDrawFramebuffer = nullptr;
mBoundReadFramebuffer = nullptr;
mActiveOcclusionQuery = nullptr;
mBoundRenderbuffer = nullptr;
mBoundVertexArray = nullptr;
mDefaultVertexArray = nullptr;
mBoundTransformFeedback = nullptr;
mDefaultTransformFeedback = nullptr;
mQuerySlot_SamplesPassed = nullptr;
mQuerySlot_TFPrimsWritten = nullptr;
mQuerySlot_TimeElapsed = nullptr;
mIndexedUniformBufferBindings.clear();
//////
@ -272,7 +274,6 @@ WebGLContext::DestroyResourcesAndContext()
ClearLinkedList(mShaders);
ClearLinkedList(mSyncs);
ClearLinkedList(mTextures);
ClearLinkedList(mTimerQueries);
ClearLinkedList(mTransformFeedbacks);
ClearLinkedList(mVertexArrays);
@ -1647,7 +1648,7 @@ WebGLContext::DummyReadFramebufferOperation(const char* funcName)
}
bool
WebGLContext::HasTimestampBits() const
WebGLContext::Has64BitTimestamps() const
{
// 'sync' provides glGetInteger64v either by supporting ARB_sync, GL3+, or GLES3+.
return gl->IsSupported(GLFeature::sync);
@ -2513,6 +2514,16 @@ WebGLContext::StartVRPresentation()
////////////////////////////////////////////////////////////////////////////////
static inline size_t
SizeOfViewElem(const dom::ArrayBufferView& view)
{
const auto& elemType = view.Type();
if (elemType == js::Scalar::MaxTypedArrayViewType) // DataViews.
return 1;
return js::Scalar::byteSize(elemType);
}
bool
WebGLContext::ValidateArrayBufferView(const char* funcName,
const dom::ArrayBufferView& view, GLuint elemOffset,
@ -2523,8 +2534,7 @@ WebGLContext::ValidateArrayBufferView(const char* funcName,
uint8_t* const bytes = view.DataAllowShared();
const size_t byteLen = view.LengthAllowShared();
const auto& elemType = view.Type();
const auto& elemSize = js::Scalar::byteSize(elemType);
const auto& elemSize = SizeOfViewElem(view);
size_t elemCount = byteLen / elemSize;
if (elemOffset > elemCount) {
@ -2592,8 +2602,9 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLContext,
mBoundRenderbuffer,
mBoundVertexArray,
mDefaultVertexArray,
mActiveOcclusionQuery,
mActiveTransformFeedbackQuery)
mQuerySlot_SamplesPassed,
mQuerySlot_TFPrimsWritten,
mQuerySlot_TimeElapsed)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY

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

@ -103,7 +103,6 @@ class WebGLShader;
class WebGLShaderPrecisionFormat;
class WebGLSync;
class WebGLTexture;
class WebGLTimerQuery;
class WebGLTransformFeedback;
class WebGLUniformLocation;
class WebGLVertexArray;
@ -446,7 +445,7 @@ public:
// a number that increments every time we have an event that causes
// all context resources to be lost.
uint32_t Generation() { return mGeneration.value(); }
uint32_t Generation() const { return mGeneration.value(); }
// This is similar to GLContext::ClearSafely, but tries to minimize the
// amount of work it does.
@ -934,10 +933,24 @@ protected:
// -----------------------------------------------------------------------------
// Queries (WebGL2ContextQueries.cpp)
protected:
WebGLRefPtr<WebGLQuery>& GetQuerySlotByTarget(GLenum target);
WebGLRefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
WebGLRefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
WebGLRefPtr<WebGLQuery>*
ValidateQuerySlotByTarget(const char* funcName, GLenum target);
public:
already_AddRefed<WebGLQuery> CreateQuery(const char* funcName = nullptr);
void DeleteQuery(WebGLQuery* query, const char* funcName = nullptr);
bool IsQuery(const WebGLQuery* query, const char* funcName = nullptr);
void BeginQuery(GLenum target, WebGLQuery* query, const char* funcName = nullptr);
void EndQuery(GLenum target, const char* funcName = nullptr);
void GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr);
void GetQueryParameter(JSContext* cx, const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr);
WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
// -----------------------------------------------------------------------------
// State and State Requests (WebGLContextState.cpp)
@ -1610,27 +1623,27 @@ protected:
// Returns false if `object` is null or not valid.
template<class ObjectType>
bool ValidateObject(const char* info, ObjectType* object);
bool ValidateObject(const char* info, const ObjectType* object);
// Returns false if `object` is not valid. Considers null to be valid.
template<class ObjectType>
bool ValidateObjectAllowNull(const char* info, ObjectType* object);
bool ValidateObjectAllowNull(const char* info, const ObjectType* object);
// Returns false if `object` is not valid, but considers deleted objects and
// null objects valid.
template<class ObjectType>
bool ValidateObjectAllowDeletedOrNull(const char* info, ObjectType* object);
bool ValidateObjectAllowDeletedOrNull(const char* info, const ObjectType* object);
// Returns false if `object` is null or not valid, but considers deleted
// objects valid.
template<class ObjectType>
bool ValidateObjectAllowDeleted(const char* info, ObjectType* object);
bool ValidateObjectAllowDeleted(const char* info, const ObjectType* object);
private:
// Like ValidateObject, but only for cases when `object` is known to not be
// null already.
template<class ObjectType>
bool ValidateObjectAssumeNonNull(const char* info, ObjectType* object);
bool ValidateObjectAssumeNonNull(const char* info, const ObjectType* object);
private:
// -------------------------------------------------------------------------
@ -1638,7 +1651,6 @@ private:
virtual WebGLVertexArray* CreateVertexArrayImpl();
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, uint32_t* alignment, const char* info) = 0;
virtual bool ValidateQueryTarget(GLenum usage, const char* info) = 0;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0;
public:
@ -1675,7 +1687,6 @@ protected:
LinkedList<WebGLShader> mShaders;
LinkedList<WebGLSync> mSyncs;
LinkedList<WebGLTexture> mTextures;
LinkedList<WebGLTimerQuery> mTimerQueries;
LinkedList<WebGLTransformFeedback> mTransformFeedbacks;
LinkedList<WebGLVertexArray> mVertexArrays;
@ -1790,7 +1801,7 @@ protected:
bool mNeedsFakeNoStencil;
bool mNeedsEmulatedLoneDepthStencil;
bool HasTimestampBits() const;
bool Has64BitTimestamps() const;
struct ScopedMaskWorkaround {
WebGLContext& mWebGL;
@ -1898,7 +1909,6 @@ public:
friend class WebGLSampler;
friend class WebGLShader;
friend class WebGLSync;
friend class WebGLTimerQuery;
friend class WebGLTransformFeedback;
friend class WebGLUniformLocation;
friend class WebGLVertexArray;
@ -1920,7 +1930,7 @@ ToSupports(WebGLContext* webgl)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
ObjectType* object)
const ObjectType* object)
{
if (object && !object->IsCompatibleWithContext(this)) {
ErrorInvalidOperation("%s: object from different WebGL context "
@ -1934,7 +1944,7 @@ WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAssumeNonNull(const char* info, const ObjectType* object)
{
MOZ_ASSERT(object);
@ -1951,7 +1961,7 @@ WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAllowNull(const char* info, const ObjectType* object)
{
if (!object)
return true;
@ -1961,7 +1971,7 @@ WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAllowDeleted(const char* info, const ObjectType* object)
{
if (!object) {
ErrorInvalidValue("%s: null object passed as argument", info);
@ -1973,7 +1983,7 @@ WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObject(const char* info, ObjectType* object)
WebGLContext::ValidateObject(const char* info, const ObjectType* object)
{
if (!object) {
ErrorInvalidValue("%s: null object passed as argument", info);

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

@ -48,7 +48,7 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext)
WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_atc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_es3_0)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
@ -112,6 +112,8 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
switch (ext) {
// In alphabetical order
// EXT_
case WebGLExtensionID::EXT_disjoint_timer_query:
return WebGLExtensionDisjointTimerQuery::IsSupported(this);
case WebGLExtensionID::EXT_texture_filter_anisotropic:
return gl->IsExtensionSupported(gl::GLContext::EXT_texture_filter_anisotropic);
@ -122,7 +124,7 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
// WEBGL_
case WebGLExtensionID::WEBGL_compressed_texture_atc:
return gl->IsExtensionSupported(gl::GLContext::AMD_compressed_ATC_texture);
case WebGLExtensionID::WEBGL_compressed_texture_es3_0:
case WebGLExtensionID::WEBGL_compressed_texture_etc:
return gl->IsSupported(gl::GLFeature::ES3_compatibility);
case WebGLExtensionID::WEBGL_compressed_texture_etc1:
return gl->IsExtensionSupported(gl::GLContext::OES_compressed_ETC1_RGB8_texture);
@ -211,14 +213,13 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
}
if (gfxPrefs::WebGLDraftExtensionsEnabled()) {
/*
switch (ext) {
case WebGLExtensionID::EXT_disjoint_timer_query:
return WebGLExtensionDisjointTimerQuery::IsSupported(this);
default:
// For warnings-as-errors.
break;
}
*/
}
}
@ -395,7 +396,7 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
case WebGLExtensionID::WEBGL_compressed_texture_atc:
obj = new WebGLExtensionCompressedTextureATC(this);
break;
case WebGLExtensionID::WEBGL_compressed_texture_es3_0:
case WebGLExtensionID::WEBGL_compressed_texture_etc:
obj = new WebGLExtensionCompressedTextureES3(this);
break;
case WebGLExtensionID::WEBGL_compressed_texture_etc1:

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

@ -264,24 +264,32 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
}
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
if (pname == LOCAL_GL_TIMESTAMP_EXT) {
GLuint64 iv = 0;
if (HasTimestampBits()) {
gl->fGetInteger64v(pname, (GLint64*)&iv);
} else {
GenerateWarning("QUERY_COUNTER_BITS_EXT for TIMESTAMP_EXT is 0.");
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
switch (pname) {
case LOCAL_GL_TIMESTAMP_EXT:
{
uint64_t val = 0;
if (Has64BitTimestamps()) {
gl->fGetInteger64v(pname, (GLint64*)&val);
} else {
gl->fGetIntegerv(pname, (GLint*)&val);
}
// TODO: JS doesn't support 64-bit integers. Be lossy and
// cast to double (53 bits)
return JS::NumberValue(val);
}
// TODO: JS doesn't support 64-bit integers. Be lossy and
// cast to double (53 bits)
return JS::NumberValue(static_cast<double>(iv));
} else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) {
// When disjoint isn't supported, leave as false.
realGLboolean disjoint = LOCAL_GL_FALSE;
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
gl->fGetBooleanv(pname, &disjoint);
case LOCAL_GL_GPU_DISJOINT_EXT:
{
realGLboolean val = false; // Not disjoint by default.
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
gl->fGetBooleanv(pname, &val);
}
return JS::BooleanValue(val);
}
return JS::BooleanValue(bool(disjoint));
default:
break;
}
}

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

@ -63,6 +63,6 @@ WebGLExtensionCompressedTextureES3::~WebGLExtensionCompressedTextureES3()
{
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3, WEBGL_compressed_texture_es3)
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3, WEBGL_compressed_texture_etc)
} // namespace mozilla

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

@ -12,245 +12,116 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/dom/BindingUtils.h"
#include "WebGLContext.h"
#include "WebGLTimerQuery.h"
#include "WebGLQuery.h"
namespace mozilla {
WebGLExtensionDisjointTimerQuery::WebGLExtensionDisjointTimerQuery(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
, mActiveQuery(nullptr)
{
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionDisjointTimerQuery::~WebGLExtensionDisjointTimerQuery()
{
}
already_AddRefed<WebGLTimerQuery>
WebGLExtensionDisjointTimerQuery::CreateQueryEXT()
already_AddRefed<WebGLQuery>
WebGLExtensionDisjointTimerQuery::CreateQueryEXT() const
{
if (mIsLost)
return nullptr;
const char funcName[] = "createQueryEXT";
if (mIsLost)
return nullptr;
RefPtr<WebGLTimerQuery> query = WebGLTimerQuery::Create(mContext);
return query.forget();
return mContext->CreateQuery(funcName);
}
void
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLQuery* query) const
{
if (mIsLost)
return;
const char funcName[] = "deleteQueryEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("deleteQueryEXT", query))
return;
query->RequestDelete();
mContext->DeleteQuery(query, funcName);
}
bool
WebGLExtensionDisjointTimerQuery::IsQueryEXT(WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::IsQueryEXT(const WebGLQuery* query) const
{
if (!query)
return false;
const char funcName[] = "isQueryEXT";
if (mIsLost)
return false;
if (!mContext->ValidateObjectAllowDeleted("isQueryEXT", query))
return false;
if (query->IsDeleted())
return false;
return true;
return mContext->IsQuery(query, funcName);
}
void
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target,
WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target, WebGLQuery* query) const
{
if (mIsLost)
return;
const char funcName[] = "beginQueryEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("beginQueryEXT", query))
return;
if (query->HasEverBeenBound() && query->Target() != target) {
mContext->ErrorInvalidOperation("beginQueryEXT: Query is already bound"
" to a different target.");
return;
}
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("beginQueryEXT: Can only begin on target"
" TIME_ELAPSED_EXT.", target);
return;
}
if (mActiveQuery) {
mContext->ErrorInvalidOperation("beginQueryEXT: A query is already"
" active.");
return;
}
mContext->MakeContextCurrent();
gl::GLContext* gl = mContext->GL();
gl->fBeginQuery(target, query->mGLName);
query->mTarget = LOCAL_GL_TIME_ELAPSED_EXT;
mActiveQuery = query;
mContext->BeginQuery(target, query, funcName);
}
void
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target)
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) const
{
if (mIsLost)
return;
const char funcName[] = "endQueryEXT";
if (mIsLost)
return;
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("endQueryEXT: Can only end on"
" TIME_ELAPSED_EXT.", target);
return;
}
if (!mActiveQuery) {
mContext->ErrorInvalidOperation("endQueryEXT: A query is not active.");
return;
}
mContext->MakeContextCurrent();
mContext->GL()->fEndQuery(target);
mActiveQuery->QueueAvailablity();
mActiveQuery = nullptr;
mContext->EndQuery(target, funcName);
}
void
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
GLenum target)
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery* query, GLenum target) const
{
if (mIsLost)
return;
const char funcName[] = "queryCounterEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("queryCounterEXT", query))
return;
if (!mContext->ValidateObject(funcName, query))
return;
if (target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnumInfo("queryCounterEXT: requires"
" TIMESTAMP_EXT.", target);
return;
}
mContext->MakeContextCurrent();
mContext->GL()->fQueryCounter(query->mGLName, target);
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
query->QueueAvailablity();
query->QueryCounter(funcName, target);
}
void
WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target,
GLenum pname,
JS::MutableHandle<JS::Value> retval)
WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const
{
if (mIsLost)
return;
const char funcName[] = "getQueryEXT";
retval.setNull();
if (mIsLost)
return;
mContext->MakeContextCurrent();
switch (pname) {
case LOCAL_GL_CURRENT_QUERY_EXT: {
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query target.",
target);
return;
}
if (mActiveQuery) {
JS::Rooted<JS::Value> v(cx);
dom::GetOrCreateDOMReflector(cx, mActiveQuery.get(), &v);
retval.set(v);
} else {
retval.set(JS::NullValue());
}
break;
}
case LOCAL_GL_QUERY_COUNTER_BITS_EXT: {
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query target.",
target);
return;
}
GLint bits = 0;
if (mContext->HasTimestampBits()) {
mContext->GL()->fGetQueryiv(target, pname, &bits);
}
retval.set(JS::Int32Value(int32_t(bits)));
break;
}
default:
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query property.",
pname);
break;
}
mContext->GetQuery(cx, target, pname, retval, funcName);
}
void
WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
WebGLTimerQuery* query,
GLenum pname,
JS::MutableHandle<JS::Value> retval)
const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval) const
{
if (mIsLost)
return;
const char funcName[] = "getQueryObjectEXT";
retval.setNull();
if (mIsLost)
return;
if (!mContext->ValidateObject("getQueryObjectEXT", query))
return;
if (query == mActiveQuery.get()) {
mContext->ErrorInvalidOperation("getQueryObjectEXT: Query must not be"
" active.");
}
mContext->MakeContextCurrent();
// XXX: Note that the query result *may change* within the same task!
// This does not follow the specification, which states that all calls
// checking query results must return the same value until the event loop
// is empty.
switch (pname) {
case LOCAL_GL_QUERY_RESULT_EXT: {
GLuint64 result = 0;
mContext->GL()->fGetQueryObjectui64v(query->mGLName,
LOCAL_GL_QUERY_RESULT_EXT,
&result);
retval.set(JS::NumberValue(result));
break;
}
case LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT: {
GLuint avail = 0;
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
&avail);
bool canBeAvailable = query->CanBeAvailable() || gfxPrefs::WebGLImmediateQueries();
retval.set(JS::BooleanValue(bool(avail) && canBeAvailable));
break;
}
default:
mContext->ErrorInvalidEnumInfo("getQueryObjectEXT: Invalid query"
" property.", pname);
break;
}
mContext->GetQueryParameter(cx, query, pname, retval, funcName);
}
bool
WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl)
{
webgl->MakeContextCurrent();
gl::GLContext* gl = webgl->GL();
return gl->IsSupported(gl::GLFeature::query_objects) &&
gl->IsSupported(gl::GLFeature::get_query_object_i64v) &&
gl->IsSupported(gl::GLFeature::query_counter); // provides GL_TIMESTAMP
}
void
WebGLExtensionDisjointTimerQuery::OnMarkLost()
{
mActiveQuery = nullptr;
webgl->MakeContextCurrent();
gl::GLContext* gl = webgl->GL();
return gl->IsSupported(gl::GLFeature::query_objects) &&
gl->IsSupported(gl::GLFeature::get_query_object_i64v) &&
gl->IsSupported(gl::GLFeature::query_counter); // provides GL_TIMESTAMP
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery, EXT_disjoint_timer_query)

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

@ -25,7 +25,6 @@ class FormatUsageAuthority;
class WebGLContext;
class WebGLShader;
class WebGLQuery;
class WebGLTimerQuery;
class WebGLVertexArray;
class WebGLExtensionBase
@ -370,29 +369,20 @@ public:
explicit WebGLExtensionDisjointTimerQuery(WebGLContext* webgl);
virtual ~WebGLExtensionDisjointTimerQuery();
already_AddRefed<WebGLTimerQuery> CreateQueryEXT();
void DeleteQueryEXT(WebGLTimerQuery* query);
bool IsQueryEXT(WebGLTimerQuery* query);
void BeginQueryEXT(GLenum target, WebGLTimerQuery* query);
void EndQueryEXT(GLenum target);
void QueryCounterEXT(WebGLTimerQuery* query, GLenum target);
void GetQueryEXT(JSContext *cx, GLenum target, GLenum pname,
JS::MutableHandle<JS::Value> retval);
void GetQueryObjectEXT(JSContext *cx, WebGLTimerQuery* query,
GLenum pname,
JS::MutableHandle<JS::Value> retval);
already_AddRefed<WebGLQuery> CreateQueryEXT() const;
void DeleteQueryEXT(WebGLQuery* query) const;
bool IsQueryEXT(const WebGLQuery* query) const;
void BeginQueryEXT(GLenum target, WebGLQuery* query) const;
void EndQueryEXT(GLenum target) const;
void QueryCounterEXT(WebGLQuery* query, GLenum target) const;
void GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const;
void GetQueryObjectEXT(JSContext* cx, const WebGLQuery* query,
GLenum pname, JS::MutableHandleValue retval) const;
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
private:
virtual void OnMarkLost() override;
/**
* An active TIME_ELAPSED query participating in a begin/end block.
*/
WebGLRefPtr<WebGLTimerQuery> mActiveQuery;
};
} // namespace mozilla

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

@ -16,7 +16,7 @@ WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext* webgl)
}
bool
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext* other)
WebGLContextBoundObject::IsCompatibleWithContext(const WebGLContext* other) const
{
return (mContext == other &&
mContextGeneration == other->Generation());

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

@ -267,7 +267,7 @@ class WebGLContextBoundObject
public:
explicit WebGLContextBoundObject(WebGLContext* webgl);
bool IsCompatibleWithContext(WebGLContext* other);
bool IsCompatibleWithContext(const WebGLContext* other) const;
WebGLContext* const mContext;
protected:

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

@ -12,22 +12,41 @@
namespace mozilla {
JSObject*
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
class AvailableRunnable final : public Runnable
{
return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
const RefPtr<WebGLQuery> mQuery;
public:
explicit AvailableRunnable(WebGLQuery* query)
: mQuery(query)
{ }
NS_IMETHOD Run() override {
mQuery->mCanBeAvailable = true;
return NS_OK;
}
};
////
static GLuint
GenQuery(gl::GLContext* gl)
{
gl->MakeCurrent();
GLuint ret = 0;
gl->fGenQueries(1, &ret);
return ret;
}
WebGLQuery::WebGLQuery(WebGLContext* webgl)
: WebGLContextBoundObject(webgl)
, mGLName(GenQuery(mContext->gl))
, mTarget(0)
, mActiveSlot(nullptr)
, mCanBeAvailable(false)
, mGLName(0)
, mType(0)
{
mContext->mQueries.insertBack(this);
mContext->MakeContextCurrent();
mContext->gl->fGenQueries(1, &mGLName);
}
void
@ -38,15 +57,212 @@ WebGLQuery::Delete()
LinkedListElement<WebGLQuery>::removeFrom(mContext->mQueries);
}
bool
WebGLQuery::IsActive() const
////
static GLenum
TargetForDriver(const gl::GLContext* gl, GLenum target)
{
if (!HasEverBeenActive())
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
break;
default:
return target;
}
if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
return target;
if (gl->IsSupported(gl::GLFeature::occlusion_query2))
return LOCAL_GL_ANY_SAMPLES_PASSED;
return LOCAL_GL_SAMPLES_PASSED;
}
void
WebGLQuery::BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot)
{
const char funcName[] = "beginQuery";
if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
return;
}
////
mTarget = target;
mActiveSlot = &slot;
*mActiveSlot = this;
////
const auto& gl = mContext->gl;
gl->MakeCurrent();
const auto driverTarget = TargetForDriver(gl, mTarget);
gl->fBeginQuery(driverTarget, mGLName);
}
void
WebGLQuery::EndQuery()
{
*mActiveSlot = nullptr;
mActiveSlot = nullptr;
mCanBeAvailable = false;
////
const auto& gl = mContext->gl;
gl->MakeCurrent();
const auto driverTarget = TargetForDriver(gl, mTarget);
gl->fEndQuery(driverTarget);
////
NS_DispatchToCurrentThread(new AvailableRunnable(this));
}
void
WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const
{
const char funcName[] = "getQueryParameter";
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
break;
default:
mContext->ErrorInvalidEnum("%s: Invalid pname: %s", funcName,
mContext->EnumName(pname));
return;
}
if (!mTarget) {
mContext->ErrorInvalidOperation("%s: Query has never been active.", funcName);
return;
}
if (mActiveSlot)
return mContext->ErrorInvalidOperation("%s: Query is still active.", funcName);
// End of validation
////
// We must usually wait for an event loop before the query can be available.
const bool canBeAvailable = (mCanBeAvailable || gfxPrefs::WebGLImmediateQueries());
if (!canBeAvailable) {
if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
retval.set(JS::BooleanValue(false));
}
return;
}
const auto& gl = mContext->gl;
gl->MakeCurrent();
uint64_t val = 0;
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
gl->fGetQueryObjectuiv(mGLName, pname, (GLuint*)&val);
retval.set(JS::BooleanValue(bool(val)));
return;
case LOCAL_GL_QUERY_RESULT:
switch (mTarget) {
case LOCAL_GL_TIME_ELAPSED_EXT:
case LOCAL_GL_TIMESTAMP_EXT:
if (mContext->Has64BitTimestamps()) {
gl->fGetQueryObjectui64v(mGLName, pname, &val);
break;
}
MOZ_FALLTHROUGH;
default:
gl->fGetQueryObjectuiv(mGLName, LOCAL_GL_QUERY_RESULT, (GLuint*)&val);
break;
}
switch (mTarget) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
retval.set(JS::BooleanValue(bool(val)));
break;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
case LOCAL_GL_TIME_ELAPSED_EXT:
case LOCAL_GL_TIMESTAMP_EXT:
retval.set(JS::NumberValue(val));
break;
default:
MOZ_CRASH("Bad `mTarget`.");
}
return;
default:
MOZ_CRASH("Bad `pname`.");
}
}
bool
WebGLQuery::IsQuery() const
{
if (IsDeleted())
return false;
WebGLRefPtr<WebGLQuery>& targetSlot = mContext->GetQuerySlotByTarget(mType);
if (!mTarget)
return false;
return targetSlot.get() == this;
return true;
}
void
WebGLQuery::DeleteQuery()
{
if (IsDeleted())
return;
if (mActiveSlot) {
EndQuery();
}
RequestDelete();
}
void
WebGLQuery::QueryCounter(const char* funcName, GLenum target)
{
if (target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnum("%s: `target` must be TIMESTAMP_EXT.", funcName,
target);
return;
}
if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
return;
}
mTarget = target;
mCanBeAvailable = false;
const auto& gl = mContext->gl;
gl->MakeCurrent();
gl->fQueryCounter(mGLName, mTarget);
NS_DispatchToCurrentThread(new AvailableRunnable(this));
}
////
JSObject*
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
{
return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)

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

@ -20,54 +20,49 @@ class WebGLQuery final
, public LinkedListElement<WebGLQuery>
, public WebGLContextBoundObject
{
friend class AvailableRunnable;
friend class WebGLRefCountedObject<WebGLQuery>;
public:
explicit WebGLQuery(WebGLContext* webgl);
const GLuint mGLName;
private:
GLenum mTarget;
WebGLRefPtr<WebGLQuery>* mActiveSlot;
class AvailableRunnable final : public Runnable
{
public:
explicit AvailableRunnable(WebGLQuery* query) : mQuery(query) { }
bool mCanBeAvailable; // Track whether the event loop has spun
NS_IMETHOD Run() override {
mQuery->mCanBeAvailable = true;
return NS_OK;
}
private:
const RefPtr<WebGLQuery> mQuery;
};
////
public:
GLenum Target() const { return mTarget; }
bool IsActive() const { return bool(mActiveSlot); }
bool IsActive() const;
bool HasEverBeenActive() const {
return mType != 0;
}
// WebGLRefCountedObject
void Delete();
// nsWrapperCache
WebGLContext* GetParentObject() const {
return mContext;
}
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
////
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
// Track whether the event loop has spun
bool mCanBeAvailable;
explicit WebGLQuery(WebGLContext* webgl);
private:
~WebGLQuery() {
DeleteOnce();
};
GLuint mGLName;
GLenum mType;
// WebGLRefCountedObject
void Delete();
friend class WebGL2Context;
public:
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
////
void BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot);
void DeleteQuery();
void EndQuery();
void GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const;
bool IsQuery() const;
void QueryCounter(const char* funcName, GLenum target);
};
} // namespace mozilla

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

@ -1,75 +0,0 @@
/* -*- 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 "WebGLTimerQuery.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
#include "WebGLContext.h"
#include "nsThreadUtils.h"
namespace mozilla {
JSObject*
WebGLTimerQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
{
return dom::WebGLTimerQueryEXTBinding::Wrap(cx, this, givenProto);
}
WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint name)
: WebGLContextBoundObject(webgl)
, mGLName(name)
, mTarget(LOCAL_GL_NONE)
, mCanBeAvailable(false)
{
mContext->mTimerQueries.insertBack(this);
}
WebGLTimerQuery::~WebGLTimerQuery()
{
DeleteOnce();
}
WebGLTimerQuery*
WebGLTimerQuery::Create(WebGLContext* webgl)
{
GLuint name = 0;
webgl->MakeContextCurrent();
webgl->gl->fGenQueries(1, &name);
return new WebGLTimerQuery(webgl, name);
}
void
WebGLTimerQuery::Delete()
{
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
gl->fDeleteQueries(1, &mGLName);
LinkedListElement<WebGLTimerQuery>::removeFrom(mContext->mTimerQueries);
}
WebGLContext*
WebGLTimerQuery::GetParentObject() const
{
return mContext;
}
void
WebGLTimerQuery::QueueAvailablity()
{
RefPtr<WebGLTimerQuery> self = this;
NS_DispatchToCurrentThread(NS_NewRunnableFunction([self] { self->mCanBeAvailable = true; }));
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTimerQuery, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTimerQuery, Release)
} // namespace mozilla

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

@ -1,54 +0,0 @@
/* -*- 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 WEBGL_TIMER_QUERY_H_
#define WEBGL_TIMER_QUERY_H_
#include "GLConsts.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLTimerQuery final
: public nsWrapperCache
, public WebGLRefCountedObject<WebGLTimerQuery>
, public LinkedListElement<WebGLTimerQuery>
, public WebGLContextBoundObject
{
public:
static WebGLTimerQuery* Create(WebGLContext* webgl);
void Delete();
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
bool CanBeAvailable() const { return mCanBeAvailable; }
void QueueAvailablity();
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const;
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTimerQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
private:
WebGLTimerQuery(WebGLContext* webgl, GLuint name);
~WebGLTimerQuery();
GLenum mTarget;
bool mCanBeAvailable;
friend class WebGLExtensionDisjointTimerQuery;
};
} // namespace mozilla
#endif // WEBGL_TIMER_QUERY_H_

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

@ -158,7 +158,7 @@ enum class WebGLExtensionID : uint8_t {
OES_vertex_array_object,
WEBGL_color_buffer_float,
WEBGL_compressed_texture_atc,
WEBGL_compressed_texture_es3_0,
WEBGL_compressed_texture_etc,
WEBGL_compressed_texture_etc1,
WEBGL_compressed_texture_pvrtc,
WEBGL_compressed_texture_s3tc,

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

@ -148,7 +148,6 @@ UNIFIED_SOURCES += [
'WebGLTexelConversions.cpp',
'WebGLTexture.cpp',
'WebGLTextureUpload.cpp',
'WebGLTimerQuery.cpp',
'WebGLTransformFeedback.cpp',
'WebGLUniformLocation.cpp',
'WebGLValidateStrings.cpp',

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

@ -10,9 +10,7 @@
<script>
'use strict';
Lastly_WithDraftExtsEnabled(function() {
EnsureExtFor('webgl', 'EXT_disjoint_timer_query');
});
EnsureExt('EXT_disjoint_timer_query');
</script>
</body>

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

@ -19,6 +19,7 @@ var defaultExts = [
// Ratified
['ANGLE_instanced_arrays' , [MACHINE_SPECIFIC, FORBID ]],
['EXT_blend_minmax' , [MACHINE_SPECIFIC, FORBID ]],
['EXT_disjoint_timer_query' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
['EXT_frag_depth' , [MACHINE_SPECIFIC, FORBID ]],
['EXT_shader_texture_lod' , [MACHINE_SPECIFIC, FORBID ]],
['EXT_texture_filter_anisotropic', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
@ -47,7 +48,6 @@ var defaultExts = [
];
var draftExts = [
['EXT_disjoint_timer_query' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]], // TODO: Actually Community Approved now.
['WEBGL_compressed_texture_es3', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
];

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

@ -82,7 +82,6 @@ skip-if = android_version == '18' #Android 4.3 aws only; bug 1030942
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
[test_webgl_compressed_texture_es3.html]
[test_webgl_disjoint_timer_query.html]
fail-if = (os == 'win' && (os_version == '6.1' || os_version == '6.2' || os_version == '10.0'))
[test_webgl_force_enable.html]
[test_webgl_request_context.html]
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests

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

@ -31,10 +31,11 @@ function doTest() {
var elapsedQuery = ext.createQueryEXT();
ok(elapsedQuery, "Query creation works.");
ok(ext.isQueryEXT(elapsedQuery), "New query is valid after creation.");
ok(!ext.isQueryEXT(elapsedQuery), "isQuery fails after creation but before bind.");
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, elapsedQuery);
is(ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT), elapsedQuery,
ok(ext.isQueryEXT(elapsedQuery), "isQuery fails after bind.");
ok(ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT) == elapsedQuery,
"Query is active after beginQueryEXT.");
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
gl.flush();
@ -65,8 +66,7 @@ function doTest() {
"Time elapsed must be at least 30 bits to hold at least 1 second of timing.");
SimpleTest.finish();
});
});
} else {
SimpleTest.finish();
}
@ -75,7 +75,7 @@ function doTest() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [['webgl.enable-draft-extensions', true]]}, doTest);
doTest();
</script>
</body>

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

@ -4004,7 +4004,7 @@ public:
}
}
~EnterLeaveDispatcher()
void Dispatch()
{
if (mEventMessage == eMouseEnter || mEventMessage == ePointerEnter) {
for (int32_t i = mTargets.Count() - 1; i >= 0; --i) {
@ -4089,6 +4089,7 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
// Fire mouseout
DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? ePointerOut : eMouseOut,
wrapper->mLastOverElement, aMovingInto);
leaveDispatcher.Dispatch();
wrapper->mLastOverFrame = nullptr;
wrapper->mLastOverElement = nullptr;
@ -4162,6 +4163,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
DispatchMouseOrPointerEvent(aMouseEvent,
isPointer ? ePointerOver : eMouseOver,
aContent, lastOverElement);
enterDispatcher->Dispatch();
wrapper->mLastOverElement = aContent;
} else {
wrapper->mLastOverFrame = nullptr;

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

@ -624,18 +624,21 @@ HTMLCanvasElement::ParseAttribute(int32_t aNamespaceID,
}
// HTMLCanvasElement::toDataURL
NS_IMETHODIMP
HTMLCanvasElement::ToDataURL(const nsAString& aType, JS::Handle<JS::Value> aParams,
JSContext* aCx, nsAString& aDataURL)
void
HTMLCanvasElement::ToDataURL(JSContext* aCx, const nsAString& aType,
JS::Handle<JS::Value> aParams,
nsAString& aDataURL,
CallerType aCallerType,
ErrorResult& aRv)
{
// do a trust check if this is a write-only canvas
if (mWriteOnly && !nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
if (mWriteOnly && aCallerType != CallerType::System) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
return ToDataURLImpl(aCx, aType, aParams, aDataURL);
aRv = ToDataURLImpl(aCx, aType, aParams, aDataURL);
}
void
@ -809,10 +812,11 @@ HTMLCanvasElement::ToBlob(JSContext* aCx,
BlobCallback& aCallback,
const nsAString& aType,
JS::Handle<JS::Value> aParams,
CallerType aCallerType,
ErrorResult& aRv)
{
// do a trust check if this is a write-only canvas
if (mWriteOnly && !nsContentUtils::IsCallerChrome()) {
if (mWriteOnly && aCallerType != CallerType::System) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
@ -863,40 +867,30 @@ HTMLCanvasElement::TransferControlToOffscreen(ErrorResult& aRv)
already_AddRefed<File>
HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
CallerType aCallerType,
ErrorResult& aRv)
{
nsCOMPtr<nsISupports> file;
aRv = MozGetAsFile(aName, aType, getter_AddRefs(file));
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(file);
RefPtr<Blob> domBlob = static_cast<Blob*>(blob.get());
MOZ_ASSERT(domBlob->IsFile());
return domBlob->ToFile();
}
NS_IMETHODIMP
HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
nsISupports** aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eMozGetAsFile);
// do a trust check if this is a write-only canvas
if ((mWriteOnly) &&
!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
if (mWriteOnly && aCallerType != CallerType::System) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
return MozGetAsBlobImpl(aName, aType, aResult);
RefPtr<File> file;
aRv = MozGetAsFileImpl(aName, aType, getter_AddRefs(file));
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return file.forget();
}
nsresult
HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName,
HTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
const nsAString& aType,
nsISupports** aResult)
File** aResult)
{
nsCOMPtr<nsIInputStream> stream;
nsAutoString type(aType);
@ -920,7 +914,7 @@ HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName,
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(OwnerDoc()->GetScopeObject());
// The File takes ownership of the buffer
nsCOMPtr<nsIDOMBlob> file =
RefPtr<File> file =
File::CreateMemoryFile(win, imgData, (uint32_t)imgSize, aName, type,
PR_Now());
@ -952,18 +946,18 @@ HTMLCanvasElement::GetContext(JSContext* aCx,
aRv);
}
NS_IMETHODIMP
already_AddRefed<nsISupports>
HTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
nsISupports **aContext)
ErrorResult& aRv)
{
if(!nsContentUtils::IsCallerChrome()) {
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
return NS_ERROR_DOM_SECURITY_ERR;
}
// Note that we're a [ChromeOnly] method, so from JS we can only be called by
// system code.
// We only support 2d shmem contexts for now.
if (!aContextId.EqualsLiteral("2d"))
return NS_ERROR_INVALID_ARG;
if (!aContextId.EqualsLiteral("2d")) {
aRv.Throw(NS_ERROR_INVALID_ARG);
return nullptr;
}
CanvasContextType contextType = CanvasContextType::Canvas2D;
@ -973,8 +967,7 @@ HTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
RefPtr<nsICanvasRenderingContextInternal> context;
context = CreateContext(contextType);
if (!context) {
*aContext = nullptr;
return NS_OK;
return nullptr;
}
mCurrentContext = context;
@ -983,15 +976,20 @@ HTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
ErrorResult dummy;
nsresult rv = UpdateContext(nullptr, JS::NullHandleValue, dummy);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return nullptr;
}
} else {
// We already have a context of some type.
if (contextType != mCurrentContextType)
return NS_ERROR_INVALID_ARG;
if (contextType != mCurrentContextType) {
aRv.Throw(NS_ERROR_INVALID_ARG);
return nullptr;
}
}
NS_ADDREF (*aContext = mCurrentContext);
return NS_OK;
nsCOMPtr<nsISupports> context(mCurrentContext);
return context.forget();
}

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

@ -16,6 +16,7 @@
#include "nsSize.h"
#include "nsError.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/CanvasRenderingContextHelper.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/layers/LayersTypes.h"
@ -176,15 +177,14 @@ public:
void ToDataURL(JSContext* aCx, const nsAString& aType,
JS::Handle<JS::Value> aParams,
nsAString& aDataURL, ErrorResult& aRv)
{
aRv = ToDataURL(aType, aParams, aCx, aDataURL);
}
nsAString& aDataURL, CallerType aCallerType,
ErrorResult& aRv);
void ToBlob(JSContext* aCx,
BlobCallback& aCallback,
const nsAString& aType,
JS::Handle<JS::Value> aParams,
CallerType aCallerType,
ErrorResult& aRv);
OffscreenCanvas* TransferControlToOffscreen(ErrorResult& aRv);
@ -204,14 +204,10 @@ public:
}
already_AddRefed<File> MozGetAsFile(const nsAString& aName,
const nsAString& aType,
CallerType aCallerType,
ErrorResult& aRv);
already_AddRefed<nsISupports> MozGetIPCContext(const nsAString& aContextId,
ErrorResult& aRv)
{
nsCOMPtr<nsISupports> context;
aRv = MozGetIPCContext(aContextId, getter_AddRefs(context));
return context.forget();
}
ErrorResult& aRv);
PrintCallback* GetMozPrintCallback() const;
void SetMozPrintCallback(PrintCallback* aCallback);
@ -371,9 +367,9 @@ protected:
const nsAString& aMimeType,
const JS::Value& aEncoderOptions,
nsAString& aDataURL);
nsresult MozGetAsBlobImpl(const nsAString& aName,
nsresult MozGetAsFileImpl(const nsAString& aName,
const nsAString& aType,
nsISupports** aResult);
File** aResult);
void CallPrintCallback();
AsyncCanvasRenderer* GetAsyncCanvasRenderer();

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

@ -3754,7 +3754,7 @@ HTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext)
// If already handling select event, don't dispatch a second.
if (!mHandlingSelectEvent) {
WidgetEvent event(nsContentUtils::LegacyIsCallerChromeOrNativeCode(), eFormSelect);
WidgetEvent event(true, eFormSelect);
mHandlingSelectEvent = true;
EventDispatcher::Dispatch(static_cast<nsIContent*>(this),

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

@ -58,7 +58,7 @@ HTMLMenuElement::~HTMLMenuElement()
}
NS_IMPL_ISUPPORTS_INHERITED(HTMLMenuElement, nsGenericHTMLElement,
nsIDOMHTMLMenuElement, nsIHTMLMenu)
nsIDOMHTMLMenuElement)
NS_IMPL_ELEMENT_CLONE(HTMLMenuElement)
@ -68,14 +68,12 @@ NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLMenuElement, Type, type,
NS_IMPL_STRING_ATTR(HTMLMenuElement, Label, label)
NS_IMETHODIMP
void
HTMLMenuElement::SendShowEvent()
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIDocument> document = GetComposedDoc();
if (!document) {
return NS_ERROR_FAILURE;
return;
}
WidgetEvent event(true, eShow);
@ -84,25 +82,13 @@ HTMLMenuElement::SendShowEvent()
nsCOMPtr<nsIPresShell> shell = document->GetShell();
if (!shell) {
return NS_ERROR_FAILURE;
return;
}
RefPtr<nsPresContext> presContext = shell->GetPresContext();
nsEventStatus status = nsEventStatus_eIgnore;
EventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
&event, nullptr, &status);
return NS_OK;
}
NS_IMETHODIMP
HTMLMenuElement::CreateBuilder(nsIMenuBuilder** _retval)
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIMenuBuilder> builder = CreateBuilder();
builder.swap(*_retval);
return NS_OK;
}
already_AddRefed<nsIMenuBuilder>
@ -117,18 +103,14 @@ HTMLMenuElement::CreateBuilder()
return builder.forget();
}
NS_IMETHODIMP
void
HTMLMenuElement::Build(nsIMenuBuilder* aBuilder)
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
if (!aBuilder) {
return NS_OK;
return;
}
BuildSubmenu(EmptyString(), this, aBuilder);
return NS_OK;
}

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

@ -9,15 +9,15 @@
#include "mozilla/Attributes.h"
#include "nsIDOMHTMLMenuElement.h"
#include "nsIHTMLMenu.h"
#include "nsGenericHTMLElement.h"
class nsIMenuBuilder;
namespace mozilla {
namespace dom {
class HTMLMenuElement final : public nsGenericHTMLElement,
public nsIDOMHTMLMenuElement,
public nsIHTMLMenu
public nsIDOMHTMLMenuElement
{
public:
explicit HTMLMenuElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
@ -30,9 +30,6 @@ public:
// nsIDOMHTMLMenuElement
NS_DECL_NSIDOMHTMLMENUELEMENT
// nsIHTMLMenu
NS_DECL_NSIHTMLMENU
virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
@ -65,11 +62,11 @@ public:
SetHTMLBoolAttr(nsGkAtoms::compact, aCompact, aError);
}
// The XPCOM SendShowEvent is OK for us
void SendShowEvent();
already_AddRefed<nsIMenuBuilder> CreateBuilder();
// The XPCOM Build is OK for us
void Build(nsIMenuBuilder* aBuilder);
protected:
virtual ~HTMLMenuElement();

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

@ -363,9 +363,6 @@ HTMLTextAreaElement::SetValue(const nsAString& aValue)
NS_IMETHODIMP
HTMLTextAreaElement::SetUserInput(const nsAString& aValue)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
return SetValueInternal(aValue, nsTextEditorState::eSetValue_BySetUserInput);
}

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

@ -20,7 +20,6 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
XPIDL_SOURCES += [
'nsIDateTimeInputArea.idl',
'nsIFormSubmitObserver.idl',
'nsIHTMLMenu.idl',
'nsIImageDocument.idl',
'nsIMenuBuilder.idl',
'nsIPhonetic.idl',

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

@ -2413,7 +2413,7 @@ nsGenericHTMLFormElement::IsLabelable() const
//----------------------------------------------------------------------
void
nsGenericHTMLElement::Click()
nsGenericHTMLElement::Click(CallerType aCallerType)
{
if (HandlingClick())
return;
@ -2432,10 +2432,8 @@ nsGenericHTMLElement::Click()
SetHandlingClick();
// Click() is never called from native code, but it may be
// called from chrome JS. Mark this event trusted if Click()
// is called from chrome code.
WidgetMouseEvent event(nsContentUtils::IsCallerChrome(),
// Mark this event trusted if Click() is called from system code.
WidgetMouseEvent event(aCallerType == CallerType::System,
eMouseClick, nullptr, WidgetMouseEvent::eReal);
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
@ -2567,13 +2565,6 @@ nsGenericHTMLElement::DispatchSimulatedClick(nsGenericHTMLElement* aElement,
nsresult
nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
{
*aEditor = nullptr;
// See also HTMLTextFieldAccessible::GetEditor.
if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_IF_ADDREF(*aEditor = GetEditorInternal());
return NS_OK;
}

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

@ -16,6 +16,7 @@
#include "nsContentCreatorFunctions.h"
#include "mozilla/ErrorResult.h"
#include "nsIDOMHTMLMenuElement.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/ValidityState.h"
#include "mozilla/dom/ElementInlines.h"
@ -103,7 +104,7 @@ public:
{
SetHTMLBoolAttr(nsGkAtoms::hidden, aHidden, aError);
}
virtual void Click();
void Click(mozilla::dom::CallerType aCallerType);
void GetAccessKey(nsString& aAccessKey)
{
GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
@ -428,10 +429,6 @@ public:
*aOffsetHeight = OffsetHeight();
return NS_OK;
}
NS_IMETHOD DOMClick() final override {
Click();
return NS_OK;
}
NS_IMETHOD GetTabIndex(int32_t* aTabIndex) final override {
*aTabIndex = TabIndex();
return NS_OK;

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

@ -116,6 +116,7 @@
#include "nsLayoutStylesheetCache.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/Unused.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -2795,17 +2796,21 @@ nsHTMLDocument::EditingStateChanged()
// Set the editor to not insert br's on return when in p
// elements by default.
// XXX Do we only want to do this for designMode?
bool unused;
rv = ExecCommand(NS_LITERAL_STRING("insertBrOnReturn"), false,
NS_LITERAL_STRING("false"), &unused);
// Note that it doesn't matter what CallerType we pass, because the callee
// doesn't use it for this command. Play it safe and pass the more
// restricted one.
ErrorResult errorResult;
Unused << ExecCommand(NS_LITERAL_STRING("insertBrOnReturn"), false,
NS_LITERAL_STRING("false"), CallerType::NonSystem,
errorResult);
if (NS_FAILED(rv)) {
if (errorResult.Failed()) {
// Editor setup failed. Editing is not on after all.
// XXX Should we reset the editable flag on nodes?
editSession->TearDownEditorOnWindow(window);
mEditingState = eOff;
return rv;
return errorResult.StealNSResult();
}
}
@ -3121,22 +3126,11 @@ ConvertToMidasInternalCommand(const nsAString & inCommandID,
dummyBool, dummyBool, true);
}
/* TODO: don't let this call do anything if the page is not done loading */
NS_IMETHODIMP
nsHTMLDocument::ExecCommand(const nsAString& commandID,
bool doShowUI,
const nsAString& value,
bool* _retval)
{
ErrorResult rv;
*_retval = ExecCommand(commandID, doShowUI, value, rv);
return rv.StealNSResult();
}
bool
nsHTMLDocument::ExecCommand(const nsAString& commandID,
bool doShowUI,
const nsAString& value,
CallerType aCallerType,
ErrorResult& rv)
{
// for optional parameters see dom/src/base/nsHistory.cpp: HistoryImpl::Go()
@ -3196,7 +3190,7 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
}
bool restricted = commandID.LowerCaseEqualsLiteral("paste");
if (restricted && !nsContentUtils::IsCallerChrome()) {
if (restricted && aCallerType != CallerType::System) {
return false;
}
@ -3260,17 +3254,10 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
return !rv.Failed();
}
NS_IMETHODIMP
nsHTMLDocument::QueryCommandEnabled(const nsAString& commandID,
bool* _retval)
{
ErrorResult rv;
*_retval = QueryCommandEnabled(commandID, rv);
return rv.StealNSResult();
}
bool
nsHTMLDocument::QueryCommandEnabled(const nsAString& commandID, ErrorResult& rv)
nsHTMLDocument::QueryCommandEnabled(const nsAString& commandID,
CallerType aCallerType,
ErrorResult& rv)
{
nsAutoCString cmdToDispatch;
if (!ConvertToMidasInternalCommand(commandID, cmdToDispatch)) {
@ -3286,7 +3273,7 @@ nsHTMLDocument::QueryCommandEnabled(const nsAString& commandID, ErrorResult& rv)
// Report false for restricted commands
bool restricted = commandID.LowerCaseEqualsLiteral("paste");
if (restricted && !nsContentUtils::IsCallerChrome()) {
if (restricted && aCallerType != CallerType::System) {
return false;
}
@ -3454,16 +3441,9 @@ nsHTMLDocument::QueryCommandState(const nsAString& commandID, ErrorResult& rv)
return retval;
}
NS_IMETHODIMP
nsHTMLDocument::QueryCommandSupported(const nsAString & commandID,
bool *_retval)
{
*_retval = QueryCommandSupported(commandID);
return NS_OK;
}
bool
nsHTMLDocument::QueryCommandSupported(const nsAString& commandID)
nsHTMLDocument::QueryCommandSupported(const nsAString& commandID,
CallerType aCallerType)
{
// Gecko technically supports all the clipboard commands including
// cut/copy/paste, but non-privileged content will be unable to call
@ -3471,7 +3451,7 @@ nsHTMLDocument::QueryCommandSupported(const nsAString& commandID)
// may also be disallowed to be called from non-privileged content.
// For that reason, we report the support status of corresponding
// command accordingly.
if (!nsContentUtils::IsCallerChrome()) {
if (aCallerType != CallerType::System) {
if (commandID.LowerCaseEqualsLiteral("paste")) {
return false;
}

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

@ -20,6 +20,7 @@
#include "nsICommandManager.h"
#include "mozilla/dom/HTMLSharedElement.h"
#include "mozilla/dom/BindingDeclarations.h"
class nsIEditor;
class nsIURI;
@ -222,13 +223,17 @@ public:
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
mozilla::ErrorResult& rv);
bool ExecCommand(const nsAString& aCommandID, bool aDoShowUI,
const nsAString& aValue, mozilla::ErrorResult& rv);
const nsAString& aValue,
mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& rv);
bool QueryCommandEnabled(const nsAString& aCommandID,
mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& rv);
bool QueryCommandIndeterm(const nsAString& aCommandID,
mozilla::ErrorResult& rv);
bool QueryCommandState(const nsAString& aCommandID, mozilla::ErrorResult& rv);
bool QueryCommandSupported(const nsAString& aCommandID);
bool QueryCommandSupported(const nsAString& aCommandID,
mozilla::dom::CallerType aCallerType);
void QueryCommandValue(const nsAString& aCommandID, nsAString& aValue,
mozilla::ErrorResult& rv);
// The XPCOM Get/SetFgColor work OK for us, since they never throw.

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

@ -1,42 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsISupports.idl"
interface nsIMenuBuilder;
/**
* A private interface.
* All methods throw NS_ERROR_DOM_SECURITY_ERR if the caller is not chrome.
*/
[scriptable, uuid(d3d068d8-e223-4228-ba39-4d6df21ba616)]
interface nsIHTMLMenu : nsISupports
{
/**
* Creates and dispatches a trusted event named "show".
* The event is not cancelable and does not bubble.
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#context-menus
*/
void sendShowEvent();
/**
* Creates a native menu builder. The builder type is dependent on menu type.
* Currently, it returns nsXULContextMenuBuilder for context menus.
* Toolbar menus are not yet supported (the method returns null).
*/
nsIMenuBuilder createBuilder();
/*
* Builds a menu by iterating over menu children.
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#building-menus-and-toolbars
* The caller can use a native builder by calling createBuilder() or provide
* a custom builder that implements the nsIMenuBuilder interface.
* A custom builder can be used for example to build native context menus
* that are not defined using <menupopup>.
*/
void build(in nsIMenuBuilder aBuilder);
};

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

@ -25,23 +25,5 @@ interface nsIDOMHTMLCanvasElement : nsISupports
attribute unsigned long width;
attribute unsigned long height;
attribute boolean mozOpaque;
// Valid calls are:
// toDataURL(); -- defaults to image/png
// toDataURL(type); -- uses given type
// toDataURL(type, params); -- uses given type, and any valid parameters
[implicit_jscontext]
DOMString toDataURL([optional] in DOMString type,
[optional] in jsval params);
// Valid calls are
// mozGetAsFile(name); -- defaults to image/png
// mozGetAsFile(name, type); -- uses given type
// The return value is a File object.
nsISupports mozGetAsFile(in DOMString name, [optional] in DOMString type);
// A Mozilla-only extension to get a canvas context backed by double-buffered
// shared memory. Only privileged callers can call this.
nsISupports MozGetIPCContext(in DOMString contextId);
};

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

@ -52,22 +52,12 @@ interface nsIDOMHTMLDocument : nsIDOMDocument
*/
attribute DOMString designMode;
boolean execCommand(in DOMString commandID,
[optional] in boolean doShowUI,
[optional] in DOMString value);
// returns true if the command is enabled (false otherwise)
boolean queryCommandEnabled(in DOMString commandID);
// returns true if the command is in a indeterminate state (false otherwise)
boolean queryCommandIndeterm(in DOMString commandID);
// returns true if the command has been executed (false otherwise)
boolean queryCommandState(in DOMString commandID);
// returns true if the command is supported on the current range
boolean queryCommandSupported(in DOMString commandID);
// returns the current value of the document or current selection for command
DOMString queryCommandValue(in DOMString commandID);

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

@ -35,8 +35,6 @@ interface nsIDOMHTMLElement : nsIDOMElement
* See <http://www.whatwg.org/html5/#the-hidden-attribute>.
*/
attribute boolean hidden;
[binaryname(DOMClick)]
void click();
attribute long tabIndex;
void focus();
[binaryname(DOMBlur)]

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

@ -1456,8 +1456,11 @@ ContentChild::RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t&
return true;
}
// Note: sending the constructor could fail, but we do not propagate the
// error back since the GPU process is fallible.
APZChild* apz = ContentProcessController::Create(aTabId);
return CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
return true;
}
bool

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

@ -1346,13 +1346,7 @@ TabChild::RecvShow(const ScreenIntSize& aSize,
return false;
}
if (!InitRenderingState(aTextureFactoryIdentifier, aLayersId, aRenderFrame)) {
// We can fail to initialize our widget if the <browser
// remote> has already been destroyed, and we couldn't hook
// into the parent-process's layer system. That's not a fatal
// error.
return true;
}
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aRenderFrame);
baseWindow->SetVisibility(true);
@ -2565,17 +2559,16 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
return true;
}
bool
void
TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame)
{
mPuppetWidget->InitIMEState();
RenderFrameChild* remoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
if (!remoteFrame) {
NS_WARNING("failed to construct RenderFrame");
return false;
if (!aRenderFrame) {
NS_WARNING("failed to construct RenderFrame");
return;
}
MOZ_ASSERT(aLayersId != 0);
@ -2586,8 +2579,7 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
PCompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
if (!compositorChild) {
NS_WARNING("failed to get CompositorBridgeChild instance");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
return;
}
ShadowLayerForwarder* lf =
@ -2605,26 +2597,15 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
PLayerTransactionChild* shadowManager =
compositorChild->SendPLayerTransactionConstructor(backends,
aLayersId, &mTextureFactoryIdentifier, &success);
if (!success) {
NS_WARNING("failed to properly allocate layer transaction");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
if (shadowManager && success) {
lf->SetShadowManager(shadowManager);
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
}
if (!shadowManager) {
NS_WARNING("failed to construct LayersChild");
// This results in |remoteFrame| being deleted.
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
lf->SetShadowManager(shadowManager);
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
}
mRemoteFrame = remoteFrame;
mRemoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
if (aLayersId != 0) {
if (!sTabChildren) {
sTabChildren = new TabChildMap;
@ -2644,7 +2625,6 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
BEFORE_FIRST_PAINT,
false);
}
return true;
}
void
@ -3003,8 +2983,6 @@ TabChild::ReinitRendering()
void
TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
{
gfxPlatform::GetPlatform()->CompositorUpdated();
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
ClientLayerManager* clm = lm->AsClientLayerManager();
MOZ_ASSERT(clm);

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

@ -728,7 +728,7 @@ private:
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
bool InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame);

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

@ -637,7 +637,6 @@ TabParent::Show(const ScreenIntSize& size, bool aParentIsActive)
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (frameLoader) {
renderFrame = new RenderFrameParent(frameLoader, &success);
MOZ_ASSERT(success);
layersId = renderFrame->GetLayersId();
renderFrame->GetTextureFactoryIdentifier(&textureFactoryIdentifier);
AddTabParentToTable(layersId, this);

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

@ -202,7 +202,7 @@ void TestUpmixStereo()
ASSERT_TRUE(channelsptr[channel][i] == GetHighValue<T>());
}
}
delete channels[0];
delete [] channels[0];
}
template<typename T>
@ -234,8 +234,8 @@ void TestDownmixStereo()
ASSERT_TRUE(output[0][i] == GetSilentValue<T>());
}
delete output[0];
delete output;
delete [] output[0];
delete [] output;
}
TEST(AudioSegment, Test)

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

@ -115,7 +115,10 @@ SimpleTest.waitForExplicitFinish();
// have to disable mixed content blocking to test https->http referrers.
SpecialPowers.pushPrefEnv({
'set': [['security.mixed_content.block_active_content', false],
['security.mixed_content.block_display_content', false]]
['security.mixed_content.block_display_content', false],
['security.mixed_content.send_hsts_priming', false],
['security.mixed_content.use_hsts', false],
]
},
function() {
// each of the iframes we create will call us back when its contents are loaded.

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

@ -272,7 +272,10 @@ function SetupPrefTestEnvironment(which, additional_prefs) {
["security.mixed_content.use_hsts",
settings.use_hsts],
["security.mixed_content.send_hsts_priming",
settings.send_hsts_priming]];
settings.send_hsts_priming],
["security.mixed_content.hsts_priming_request_timeout",
30000],
];
if (additional_prefs) {
for (let idx in additional_prefs) {

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

@ -1251,6 +1251,8 @@ var interfaceNamesInGlobalScope =
"WebGLUniformLocation",
// IMPORTANT: Do not change this list without review from a DOM peer!
"WebGLVertexArrayObject",
// IMPORTANT: Do not change this list without review from a DOM peer!
"WebGLVertexArrayObjectOES",
// IMPORTANT: Do not change this list without review from a DOM peer!
"WebKitCSSMatrix",
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -17,6 +17,7 @@
#include "nsEscape.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsIIOService.h"
#include "nsIURIWithQuery.h"
#include "nsIURL.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
@ -521,37 +522,37 @@ URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const
{
aPathname.Truncate();
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
if (!url) {
nsAutoCString path;
nsresult rv = mURI->GetPath(path);
if (NS_FAILED(rv)){
// Do not throw! Not having a valid URI or URL should result in an empty
// string.
return;
// Do not throw! Not having a valid URI or URL should result in an empty
// string.
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
if (url) {
nsAutoCString file;
nsresult rv = url->GetFilePath(file);
if (NS_SUCCEEDED(rv)) {
CopyUTF8toUTF16(file, aPathname);
}
CopyUTF8toUTF16(path, aPathname);
return;
}
nsAutoCString file;
nsresult rv = url->GetFilePath(file);
nsAutoCString path;
nsresult rv = mURI->GetPath(path);
if (NS_SUCCEEDED(rv)) {
CopyUTF8toUTF16(file, aPathname);
CopyUTF8toUTF16(path, aPathname);
}
}
void
URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv)
{
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
if (!url) {
// Ignore failures to be compatible with NS4.
// Do not throw!
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
if (url) {
url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
return;
}
url->SetFilePath(NS_ConvertUTF16toUTF8(aPathname));
}
void
@ -559,17 +560,19 @@ URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const
{
aSearch.Truncate();
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
if (!url) {
// Do not throw! Not having a valid URI or URL should result in an empty
// string.
return;
}
// Do not throw! Not having a valid URI or URL should result in an empty
// string.
nsAutoCString search;
nsresult rv = url->GetQuery(search);
if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
nsresult rv;
nsCOMPtr<nsIURIWithQuery> url(do_QueryInterface(mURI));
if (url) {
rv = url->GetQuery(search);
if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
CopyUTF8toUTF16(NS_LITERAL_CSTRING("?") + search, aSearch);
}
return;
}
}
@ -598,13 +601,13 @@ URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv)
void
URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv)
{
nsCOMPtr<nsIURL> url(do_QueryInterface(mURI));
if (!url) {
// Ignore failures to be compatible with NS4.
// Ignore failures to be compatible with NS4.
nsCOMPtr<nsIURIWithQuery> uriWithQuery(do_QueryInterface(mURI));
if (uriWithQuery) {
uriWithQuery->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
return;
}
url->SetQuery(NS_ConvertUTF16toUTF8(aSearch));
}
} // anonymous namespace

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

@ -217,6 +217,16 @@
pathname: 'blank',
skip_setters: false,
},
{ url: 'foo:bar?what#yeah',
base: undefined,
error: false,
protocol: 'foo:',
pathname: 'bar',
search: '?what',
hash: '#yeah',
skip_setters: false,
},
];
while(tests.length) {
@ -387,5 +397,40 @@
url = new URL("scheme://tmp\\test", base);
is(url.href, "scheme://tmp\\test");
</script>
<script>
var url = new URL("scheme:path/to/file?query#hash");
is(url.href, "scheme:path/to/file?query#hash");
is(url.pathname, "path/to/file");
is(url.search, "?query");
is(url.hash, "#hash");
// pathname cannot be overwritten.
url.pathname = "new/path?newquery#newhash";
is(url.href, "scheme:path/to/file?query#hash");
url.search = "?newquery#newhash";
is(url.href, "scheme:path/to/file?newquery%23newhash#hash");
// nulls get encoded, whitespace gets stripped
url = new URL("scheme:pa\0\nth/to/fi\0\nle?qu\0\nery#ha\0\nsh");
is(url.href, "scheme:pa%00th/to/fi%00le?qu%00ery#ha%00sh");
url.search = "new\0\nquery";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#ha%00sh");
url.hash = "new\0\nhash";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#new%00%0Ahash");
url = new URL("scheme:path#hash");
is(url.href, "scheme:path#hash");
url.search = "query";
is(url.href, "scheme:path?query#hash");
url.hash = "";
is(url.href, "scheme:path?query");
url.hash = "newhash";
is(url.href, "scheme:path?query#newhash");
url.search = "";
is(url.href, "scheme:path#newhash");
</script>
</body>
</html>

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

@ -22,10 +22,10 @@ interface HTMLCanvasElement : HTMLElement {
[Throws]
nsISupports? getContext(DOMString contextId, optional any contextOptions = null);
[Throws]
[Throws, NeedsCallerType]
DOMString toDataURL(optional DOMString type = "",
optional any encoderOptions);
[Throws]
[Throws, NeedsCallerType]
void toBlob(BlobCallback _callback,
optional DOMString type = "",
optional any encoderOptions);
@ -35,10 +35,13 @@ interface HTMLCanvasElement : HTMLElement {
partial interface HTMLCanvasElement {
[Pure, SetterThrows]
attribute boolean mozOpaque;
[Throws]
[Throws, NeedsCallerType]
File mozGetAsFile(DOMString name, optional DOMString? type = null);
// A Mozilla-only extension to get a canvas context backed by double-buffered
// shared memory. Only privileged callers can call this.
[ChromeOnly, Throws]
nsISupports? MozGetIPCContext(DOMString contextId);
attribute PrintCallback? mozPrintCallback;
[Throws, UnsafeInPrerendering, Pref="canvas.capturestream.enabled"]

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

@ -45,15 +45,16 @@ interface HTMLDocument : Document {
[SetterThrows, NeedsSubjectPrincipal]
attribute DOMString designMode;
[Throws]
[Throws, NeedsCallerType]
boolean execCommand(DOMString commandId, optional boolean showUI = false,
optional DOMString value = "");
[Throws]
[Throws, NeedsCallerType]
boolean queryCommandEnabled(DOMString commandId);
[Throws]
boolean queryCommandIndeterm(DOMString commandId);
[Throws]
boolean queryCommandState(DOMString commandId);
[NeedsCallerType]
boolean queryCommandSupported(DOMString commandId);
[Throws]
DOMString queryCommandValue(DOMString commandId);

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

@ -28,6 +28,7 @@ interface HTMLElement : Element {
// user interaction
[SetterThrows, Pure]
attribute boolean hidden;
[NeedsCallerType]
void click();
[SetterThrows, Pure]
attribute long tabIndex;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270364
[LegacyUnenumerableNamedProperties]
interface MimeTypeArray {
readonly attribute unsigned long length;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270366
[LegacyUnenumerableNamedProperties]
interface Plugin {
readonly attribute DOMString description;
readonly attribute DOMString filename;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270366
[LegacyUnenumerableNamedProperties]
interface PluginArray {
readonly attribute unsigned long length;

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

@ -10,10 +10,6 @@
typedef long long GLint64;
typedef unsigned long long GLuint64;
[Pref="webgl.enable-webgl2"]
interface WebGLQuery {
};
[Pref="webgl.enable-webgl2"]
interface WebGLSampler {
};
@ -625,7 +621,7 @@ interface WebGL2RenderingContext : WebGLRenderingContext
[WebGLHandlesContextLoss] GLboolean isQuery(WebGLQuery? query);
void beginQuery(GLenum target, WebGLQuery? query);
void endQuery(GLenum target);
WebGLQuery? getQuery(GLenum target, GLenum pname);
any getQuery(GLenum target, GLenum pname);
any getQueryParameter(WebGLQuery? query, GLenum pname);
/* Sampler Objects */

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

@ -80,7 +80,6 @@ interface WebGLTexture {
interface WebGLUniformLocation {
};
[NoInterfaceObject]
interface WebGLVertexArrayObjectOES {
};
@ -807,7 +806,7 @@ interface WEBGL_compressed_texture_atc
};
[NoInterfaceObject]
interface WEBGL_compressed_texture_es3
interface WEBGL_compressed_texture_etc
{
const GLenum COMPRESSED_R11_EAC = 0x9270;
const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271;
@ -1003,8 +1002,7 @@ interface EXT_blend_minmax {
const GLenum MAX_EXT = 0x8008;
};
[NoInterfaceObject]
interface WebGLTimerQueryEXT {
interface WebGLQuery {
};
[NoInterfaceObject]
@ -1017,12 +1015,12 @@ interface EXT_disjoint_timer_query {
const GLenum TIMESTAMP_EXT = 0x8E28;
const GLenum GPU_DISJOINT_EXT = 0x8FBB;
WebGLTimerQueryEXT? createQueryEXT();
void deleteQueryEXT(WebGLTimerQueryEXT? query);
[WebGLHandlesContextLoss] boolean isQueryEXT(WebGLTimerQueryEXT? query);
void beginQueryEXT(GLenum target, WebGLTimerQueryEXT? query);
WebGLQuery? createQueryEXT();
void deleteQueryEXT(WebGLQuery? query);
[WebGLHandlesContextLoss] boolean isQueryEXT(WebGLQuery? query);
void beginQueryEXT(GLenum target, WebGLQuery? query);
void endQueryEXT(GLenum target);
void queryCounterEXT(WebGLTimerQueryEXT? query, GLenum target);
void queryCounterEXT(WebGLQuery? query, GLenum target);
any getQueryEXT(GLenum target, GLenum pname);
any getQueryObjectEXT(WebGLTimerQueryEXT? query, GLenum pname);
any getQueryObjectEXT(WebGLQuery? query, GLenum pname);
};

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

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<body>
<script>
function syncXHR() {
let xhr = new XMLHttpRequest();
xhr.open("GET", window.location, false);
xhr.send(null);
}
addEventListener('load', evt => {
syncXHR();
document.open();
document.write(
'<body>' +
'<iframe src="about:blank"></iframe>' +
'<script>window.opener.postMessage("DONE", "*");</' + 'script>' +
'</body>');
document.close();
}, { once: true });
</script>
</body>

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

@ -63,6 +63,7 @@ support-files =
sync_xhr_unload.sjs
iframe_sync_xhr_unload.html
empty.html
file_sync_xhr_document_write_with_iframe.html
[test_bug1300552.html]
[test_html_in_xhr.html]
@ -111,3 +112,4 @@ support-files = test_XHR_timeout.js
[test_XHRDocURI.html]
[test_XHRResponseURL.html]
[test_XHRSendData.html]
[test_sync_xhr_document_write_with_iframe.html]

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

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script>
function runTest() {
let w = window.open('file_sync_xhr_document_write_with_iframe.html');
addEventListener('message', evt => {
is(evt.data, 'DONE');
w.close();
SimpleTest.finish();
}, { once: true });
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTest);
</script>
</pre>
</body>
</html>

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

@ -45,6 +45,7 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorSession)
virtual bool Reset(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier) = 0;
virtual void Shutdown() = 0;

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

@ -60,6 +60,7 @@ GPUProcessManager::Shutdown()
GPUProcessManager::GPUProcessManager()
: mTaskFactory(this),
mNextLayerTreeId(0),
mNextResetSequenceNo(0),
mNumProcessAttempts(0),
mDeviceResetCount(0),
mProcess(nullptr),
@ -306,10 +307,12 @@ GPUProcessManager::OnProcessDeviceReset(GPUProcessHost* aHost)
HandleProcessLost();
return;
}
uint64_t seqNo = GetNextDeviceResetSequenceNumber();
// We're good, do a reset like normal
for (auto& session : mRemoteSessions) {
session->NotifyDeviceReset();
session->NotifyDeviceReset(seqNo);
}
}

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

@ -148,6 +148,14 @@ public:
return mNumProcessAttempts > 0;
}
// Returns the next compositor reset sequence number, a monotonic counter
// for when the compositing device resets. Since content processes are
// notified of resets through each individual tab, this allows content to
// only re-acquire devices once for each reset.
uint64_t GetNextDeviceResetSequenceNumber() {
return ++mNextResetSequenceNo;
}
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();
@ -213,6 +221,7 @@ private:
ipc::TaskFactory<GPUProcessManager> mTaskFactory;
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
uint64_t mNextLayerTreeId;
uint64_t mNextResetSequenceNo;
uint32_t mNumProcessAttempts;
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;

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

@ -61,9 +61,11 @@ InProcessCompositorSession::GetAPZCTreeManager() const
}
bool
InProcessCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier)
InProcessCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier)
{
return mCompositorBridgeParent->ResetCompositor(aBackendHints, aOutIdentifier);
return mCompositorBridgeParent->ResetCompositor(aBackendHints, aSeqNo, aOutIdentifier);
}
void

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

@ -30,7 +30,9 @@ public:
CompositorBridgeParent* GetInProcessBridge() const override;
void SetContentController(GeckoContentController* aController) override;
RefPtr<IAPZCTreeManager> GetAPZCTreeManager() const override;
bool Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier) override;
bool Reset(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier) override;
void Shutdown() override;
private:

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

@ -39,10 +39,10 @@ RemoteCompositorSession::~RemoteCompositorSession()
}
void
RemoteCompositorSession::NotifyDeviceReset()
RemoteCompositorSession::NotifyDeviceReset(uint64_t aSeqNo)
{
MOZ_ASSERT(mWidget);
mWidget->OnRenderingDeviceReset();
mWidget->OnRenderingDeviceReset(aSeqNo);
}
void
@ -87,10 +87,12 @@ RemoteCompositorSession::GetAPZCTreeManager() const
}
bool
RemoteCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier)
RemoteCompositorSession::Reset(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier)
{
bool didReset;
Unused << mCompositorBridgeChild->SendReset(aBackendHints, &didReset, aOutIdentifier);
Unused << mCompositorBridgeChild->SendReset(aBackendHints, aSeqNo, &didReset, aOutIdentifier);
return didReset;
}

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

@ -28,10 +28,12 @@ public:
GeckoContentController* GetContentController();
nsIWidget* GetWidget();
RefPtr<IAPZCTreeManager> GetAPZCTreeManager() const override;
bool Reset(const nsTArray<LayersBackend>& aBackendHints, TextureFactoryIdentifier* aOutIdentifier) override;
bool Reset(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier) override;
void Shutdown() override;
void NotifyDeviceReset();
void NotifyDeviceReset(uint64_t aSeqNo);
void NotifySessionLost();
private:

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

@ -1182,7 +1182,6 @@ TextureClient::CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
TextureAllocationFlags aAllocFlags)
{
// also test the validity of aAllocator
MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
if (!aAllocator || !aAllocator->IPCOpen()) {
return nullptr;
}
@ -1220,7 +1219,6 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
MOZ_ASSERT(!aAllocator || aAllocator->GetLayersIPCActor()->IPCOpen());
if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
return nullptr;
}
@ -1247,8 +1245,6 @@ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
// also test the validity of aAllocator
MOZ_ASSERT(!aAllocator || aAllocator->GetLayersIPCActor()->IPCOpen());
if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
return nullptr;
}

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

@ -338,12 +338,21 @@ CompositorBridgeChild::RecvInvalidateLayers(const uint64_t& aLayersId)
bool
CompositorBridgeChild::RecvCompositorUpdated(const uint64_t& aLayersId,
const TextureFactoryIdentifier& aNewIdentifier)
const TextureFactoryIdentifier& aNewIdentifier,
const uint64_t& aSeqNo)
{
if (mLayerManager) {
// This case is handled directly by nsBaseWidget.
MOZ_ASSERT(aLayersId == 0);
} else if (aLayersId != 0) {
// Update gfxPlatform if this is the first time we're seeing this compositor
// update (we will get an update for each connected tab).
static uint64_t sLastSeqNo = 0;
if (sLastSeqNo != aSeqNo) {
gfxPlatform::GetPlatform()->CompositorUpdated();
sLastSeqNo = aSeqNo;
}
if (dom::TabChild* child = dom::TabChild::GetFrom(aLayersId)) {
child->CompositorUpdated(aNewIdentifier);
}

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

@ -103,7 +103,8 @@ public:
virtual bool
RecvCompositorUpdated(const uint64_t& aLayersId,
const TextureFactoryIdentifier& aNewIdentifier) override;
const TextureFactoryIdentifier& aNewIdentifier,
const uint64_t& aSeqNo) override;
virtual bool
RecvOverfill(const uint32_t &aOverfill) override;

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

@ -684,10 +684,13 @@ CompositorBridgeParent::Initialize()
}
bool
CompositorBridgeParent::RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier)
CompositorBridgeParent::RecvReset(nsTArray<LayersBackend>&& aBackendHints,
const uint64_t& aSeqNo,
bool* aResult,
TextureFactoryIdentifier* aOutIdentifier)
{
Maybe<TextureFactoryIdentifier> newIdentifier;
ResetCompositorTask(aBackendHints, &newIdentifier);
ResetCompositorTask(aBackendHints, aSeqNo, &newIdentifier);
if (newIdentifier) {
*aResult = true;
@ -2054,6 +2057,7 @@ CompositorBridgeParent::InvalidateRemoteLayers()
bool
CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier)
{
Maybe<TextureFactoryIdentifier> newIdentifier;
@ -2062,10 +2066,12 @@ CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendH
CompositorLoop()->PostTask(NewRunnableMethod
<StoreCopyPassByConstLRef<nsTArray<LayersBackend>>,
Maybe<TextureFactoryIdentifier>*>(this,
&CompositorBridgeParent::ResetCompositorTask,
aBackendHints,
&newIdentifier));
uint64_t,
Maybe<TextureFactoryIdentifier>*>(this,
&CompositorBridgeParent::ResetCompositorTask,
aBackendHints,
aSeqNo,
&newIdentifier));
mResetCompositorMonitor.Wait();
}
@ -2082,6 +2088,7 @@ CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendH
// monitor.
void
CompositorBridgeParent::ResetCompositorTask(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
Maybe<TextureFactoryIdentifier>* aOutNewIdentifier)
{
// Perform the reset inside a lock, so the main thread can wake up as soon as
@ -2108,7 +2115,7 @@ CompositorBridgeParent::ResetCompositorTask(const nsTArray<LayersBackend>& aBack
MonitorAutoLock lock(*sIndirectLayerTreesLock);
ForEachIndirectLayerTree([&] (LayerTreeState* lts, uint64_t layersId) -> void {
if (CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent) {
Unused << cpcp->SendCompositorUpdated(layersId, newIdentifier.value());
Unused << cpcp->SendCompositorUpdated(layersId, newIdentifier.value(), aSeqNo);
if (LayerTransactionParent* ltp = lts->mLayerTree) {
ltp->AddPendingCompositorUpdate();

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

@ -262,7 +262,10 @@ public:
bool Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint);
virtual bool RecvInitialize(const uint64_t& aRootLayerTreeId) override;
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier) override;
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints,
const uint64_t& aSeqNo,
bool* aResult,
TextureFactoryIdentifier* aOutIdentifier) override;
virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override;
virtual bool RecvRequestOverfill() override;
virtual bool RecvWillClose() override;
@ -349,6 +352,7 @@ public:
* minimize the amount of time the main thread is blocked.
*/
bool ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
TextureFactoryIdentifier* aOutIdentifier);
/**
@ -584,6 +588,7 @@ protected:
RefPtr<Compositor> NewCompositor(const nsTArray<LayersBackend>& aBackendHints);
void ResetCompositorTask(const nsTArray<LayersBackend>& aBackendHints,
uint64_t aSeqNo,
Maybe<TextureFactoryIdentifier>* aOutNewIdentifier);
Maybe<TextureFactoryIdentifier> ResetCompositorImpl(const nsTArray<LayersBackend>& aBackendHints);

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

@ -42,7 +42,11 @@ public:
// FIXME/bug 774388: work out what shutdown protocol we need.
virtual bool RecvInitialize(const uint64_t& aRootLayerTreeId) override { return false; }
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints, bool* aResult, TextureFactoryIdentifier* aOutIdentifier) override { return false; }
virtual bool RecvReset(nsTArray<LayersBackend>&& aBackendHints,
const uint64_t& aSeqNo,
bool* aResult,
TextureFactoryIdentifier* aOutIdentifier) override
{ return false; }
virtual bool RecvRequestOverfill() override { return true; }
virtual bool RecvWillClose() override { return true; }
virtual bool RecvPause() override { return true; }

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

@ -62,8 +62,12 @@ child:
// The compositor type or device has changed, and a new texture factory
// identifier is available. Layers must be invalidated and the new identifier
// must be propagated.
async CompositorUpdated(uint64_t layersId, TextureFactoryIdentifier newIdentifier);
// must be propagated. The sequence number is a generation count for the
// compositor.
async CompositorUpdated(
uint64_t layersId,
TextureFactoryIdentifier newIdentifier,
uint64_t seqNo);
// The compositor completed a layers transaction. id is the layers id
// of the child layer tree that was composited (or 0 when notifying
@ -123,7 +127,8 @@ parent:
// When out-of-process, this must be called to finish initialization.
sync Initialize(uint64_t rootLayerTreeId);
sync Reset(LayersBackend[] aBackendHints) returns (bool aResult, TextureFactoryIdentifier aOutIdentifier);
sync Reset(LayersBackend[] aBackendHints, uint64_t aSeqNo)
returns (bool aResult, TextureFactoryIdentifier aOutIdentifier);
// Returns whether this Compositor has APZ enabled or not.
sync AsyncPanZoomEnabled(uint64_t layersId) returns (bool aHasAPZ);

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

@ -665,14 +665,18 @@ DeviceManagerDx::HasDeviceReset(DeviceResetReason* aOutReason)
MutexAutoLock lock(mDeviceLock);
if (mDeviceResetReason) {
*aOutReason = mDeviceResetReason.value();
if (aOutReason) {
*aOutReason = mDeviceResetReason.value();
}
return true;
}
DeviceResetReason reason;
if (GetAnyDeviceRemovedReason(&reason)) {
mDeviceResetReason = Some(reason);
*aOutReason = reason;
if (aOutReason) {
*aOutReason = reason;
}
return true;
}

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

@ -724,10 +724,9 @@ gfxShapedText::SetGlyphs(uint32_t aIndex, CompressedGlyph aGlyph,
#define ZWNJ 0x200C
#define ZWJ 0x200D
static inline bool
IsDefaultIgnorable(uint32_t aChar)
IsIgnorable(uint32_t aChar)
{
return GetIdentifierModification(aChar) == XIDMOD_DEFAULT_IGNORABLE ||
aChar == ZWNJ || aChar == ZWJ;
return (IsDefaultIgnorable(aChar)) || aChar == ZWNJ || aChar == ZWJ;
}
void
@ -743,7 +742,7 @@ gfxShapedText::SetMissingGlyph(uint32_t aIndex, uint32_t aChar, gfxFont *aFont)
DetailedGlyph *details = AllocateDetailedGlyphs(aIndex, 1);
details->mGlyphID = aChar;
if (IsDefaultIgnorable(aChar)) {
if (IsIgnorable(aChar)) {
// Setting advance width to zero will prevent drawing the hexbox
details->mAdvance = 0;
} else {
@ -761,7 +760,7 @@ gfxShapedText::SetMissingGlyph(uint32_t aIndex, uint32_t aChar, gfxFont *aFont)
bool
gfxShapedText::FilterIfIgnorable(uint32_t aIndex, uint32_t aCh)
{
if (IsDefaultIgnorable(aCh)) {
if (IsIgnorable(aCh)) {
// There are a few default-ignorables of Letter category (currently,
// just the Hangul filler characters) that we'd better not discard
// if they're followed by additional characters in the same cluster.

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

@ -191,10 +191,13 @@ gfxGDIFont::Initialize()
// initialize its metrics so we can calculate size adjustment
Initialize();
// Unless the font was so small that GDI metrics rounded to zero,
// calculate the properly adjusted size, and then proceed
// to recreate mFont and recalculate metrics
gfxFloat aspect = mMetrics->xHeight / mMetrics->emHeight;
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
if (mMetrics->xHeight > 0.0 && mMetrics->emHeight > 0.0) {
gfxFloat aspect = mMetrics->xHeight / mMetrics->emHeight;
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
}
// delete the temporary font and metrics
::DeleteObject(mFont);

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

@ -636,6 +636,16 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
if (!saneData) {
mFontSet->LogMessage(this, "rejected by sanitizer");
} else {
// Check whether saneData is a known OpenType format; it might be
// a TrueType Collection, which OTS would accept but we don't yet
// know how to handle. If so, discard.
if (gfxFontUtils::DetermineFontDataType(saneData, saneLen) !=
GFX_USERFONT_OPENTYPE) {
mFontSet->LogMessage(this, "not a supported OpenType format");
free((void*)saneData);
saneData = nullptr;
}
}
if (saneData) {
if (saneLen) {

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

@ -23,19 +23,21 @@
# - HangulSyllableType.txt
# - LineBreak.txt
# - EastAsianWidth.txt
# - DerivedCoreProperties.txt
# - ReadMe.txt (to record version/date of the UCD)
# - Unihan_Variants.txt (from Unihan.zip)
# though this may change if we find a need for additional properties.
#
# The Unicode data files listed above should be together in one directory.
#
# We also require the file
# http://www.unicode.org/Public/security/latest/xidmodifications.txt
# This file should be in a sub-directory "security" immediately below the
# We also require the files
# http://www.unicode.org/Public/security/latest/IdentifierStatus.txt
# http://www.unicode.org/Public/security/latest/IdentifierType.txt
# These files should be in a sub-directory "security" immediately below the
# directory containing the other Unicode data files.
#
# We also require the latest data file for UTR50, currently revision-13:
# http://www.unicode.org/Public/vertical/revision-13/VerticalOrientation-13.txt
# We also require the latest data file for UTR50, currently revision-15:
# http://www.unicode.org/Public/vertical/revision-15/VerticalOrientation-15.txt
# This file should be in a sub-directory "vertical" immediately below the
# directory containing the other Unicode data files.
#
@ -140,20 +142,35 @@ sub readIcuHeader
die "didn't find ICU script codes\n" if $sc == -1;
my %xidmodCode = (
'Recommended' => 0,
'Inclusion' => 1,
'Uncommon_Use' => 2,
'Technical' => 3,
'Obsolete' => 4,
'Aspirational' => 5,
'Limited_Use' => 6,
'Exclusion' => 7,
'Not_XID' => 8,
'Not_NFKC' => 9,
'Default_Ignorable' => 10,
'Deprecated' => 11,
'not-chars' => 12
# We don't currently store these values; %idType is used only to check that
# properties listed in the IdentifierType.txt file are recognized. We record
# only the %mappedIdType values that are used by nsIDNService::isLabelSafe.
# In practice, it would be sufficient for us to read only the last value in
# IdentifierType.txt, but we check that all values are known so that we'll get
# a warning if future updates introduce new ones, and can consider whether
# they need to be taken into account.
my %idType = (
"Not_Character" => 0,
"Recommended" => 1,
"Inclusion" => 2,
"Uncommon_Use" => 3,
"Technical" => 4,
"Obsolete" => 5,
"Aspirational" => 6,
"Limited_Use" => 7,
"Exclusion" => 8,
"Not_XID" => 9,
"Not_NFKC" => 10,
"Default_Ignorable" => 11,
"Deprecated" => 12
);
# These match the IdentifierType enum in nsUnicodeProperties.h.
my %mappedIdType = (
"Restricted" => 0,
"Allowed" => 1,
"Aspirational" => 2 # for Aspirational characters that are not excluded
# by another attribute.
);
my %bidicategoryCode = (
@ -229,7 +246,10 @@ my %lineBreakCode = ( # ordering matches ICU's ULineBreak enum
"CP" => 36,
"CJ" => 37,
"HL" => 38,
"RI" => 39
"RI" => 39,
"EB" => 40,
"EM" => 41,
"ZWJ" => 42
);
my %eastAsianWidthCode = (
@ -249,7 +269,7 @@ my @mirror;
my @pairedBracketType;
my @hangul;
my @casemap;
my @xidmod;
my @idtype;
my @numericvalue;
my @hanVariant;
my @bidicategory;
@ -258,13 +278,14 @@ my @fullWidthInverse;
my @verticalOrientation;
my @lineBreak;
my @eastAsianWidthFWH;
my @defaultIgnorable;
for (my $i = 0; $i < 0x110000; ++$i) {
$script[$i] = $scriptCode{"UNKNOWN"};
$category[$i] = $catCode{"UNASSIGNED"};
$combining[$i] = 0;
$pairedBracketType[$i] = 0;
$casemap[$i] = 0;
$xidmod[$i] = $xidmodCode{"not-chars"};
$idtype[$i] = $mappedIdType{'Restricted'};
$numericvalue[$i] = -1;
$hanVariant[$i] = 0;
$bidicategory[$i] = $bidicategoryCode{"L"};
@ -273,6 +294,7 @@ for (my $i = 0; $i < 0x110000; ++$i) {
$verticalOrientation[$i] = 1; # default for unlisted codepoints is 'R'
$lineBreak[$i] = $lineBreakCode{"XX"};
$eastAsianWidthFWH[$i] = 0;
$defaultIgnorable[$i] = 0;
}
# blocks where the default for bidi category is not L
@ -557,25 +579,67 @@ while (<FH>) {
}
close FH;
# read xidmodifications.txt
open FH, "< $UNICODE/security/xidmodifications.txt" or die "can't open UCD file xidmodifications.txt\n";
# read DerivedCoreProperties.txt (for Default-Ignorables)
open FH, "< $UNICODE/DerivedCoreProperties.txt" or die "can't open UCD file DerivedCoreProperties.txt\n";
push @versionInfo, "";
while (<FH>) {
chomp;
push @versionInfo, $_;
last if /Date:/;
}
while (<FH>) {
s/#.*//;
if (m/([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))*\s*;\s*Default_Ignorable_Code_Point/) {
my $start = hex "0x$1";
my $end = (defined $2) ? hex "0x$2" : $start;
for (my $i = $start; $i <= $end; ++$i) {
$defaultIgnorable[$i] = 1;
}
}
}
close FH;
# read IdentifierStatus.txt
open FH, "< $UNICODE/security/IdentifierStatus.txt" or die "can't open UCD file IdentifierStatus.txt\n";
push @versionInfo, "";
while (<FH>) {
chomp;
unless (/\xef\xbb\xbf/) {
push @versionInfo, $_;
}
last if /Generated:/;
s/\xef\xbb\xbf//;
push @versionInfo, $_;
last if /Date:/;
}
while (<FH>) {
if (m/([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))*\s+;\s+[^ ]+\s+;\s+([^ ]+)/) {
my $xidmod = $3;
warn "unknown Identifier Modification $xidmod" unless exists $xidmodCode{$xidmod};
$xidmod = $xidmodCode{$xidmod};
if (m/([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))*\s+;\s+Allowed/) {
my $start = hex "0x$1";
my $end = (defined $2) ? hex "0x$2" : $start;
for (my $i = $start; $i <= $end; ++$i) {
$xidmod[$i] = $xidmod;
$idtype[$i] = $mappedIdType{'Allowed'};
}
}
}
close FH;
# read IdentifierType.txt, to find Aspirational characters
open FH, "< $UNICODE/security/IdentifierType.txt" or die "can't open UCD file IdentifierType.txt\n";
push @versionInfo, "";
while (<FH>) {
chomp;
s/\xef\xbb\xbf//;
push @versionInfo, $_;
last if /Date:/;
}
while (<FH>) {
if (m/([0-9A-F]{4,6})(?:\.\.([0-9A-F]{4,6}))*\s+;\s+([^#]+)/) {
my $idtype = $3;
foreach (split(/ /, $idtype)) {
warn "unknown Identifier Type $_" unless exists $idType{$_};
}
my $start = hex "0x$1";
my $end = (defined $2) ? hex "0x$2" : $start;
if ($idtype =~ /Aspirational/ and (not $idtype =~ /Exclusion|Not_XID|Not_NFKC/)) {
for (my $i = $start; $i <= $end; ++$i) {
$idtype[$i] = $mappedIdType{'Aspirational'};
}
}
}
}
@ -617,8 +681,8 @@ while (<FH>) {
}
close FH;
# read VerticalOrientation-13.txt
open FH, "< $UNICODE/vertical/VerticalOrientation-13.txt" or die "can't open UTR50 data file VerticalOrientation-13.txt\n";
# read VerticalOrientation-15.txt
open FH, "< $UNICODE/vertical/VerticalOrientation-15.txt" or die "can't open UTR50 data file VerticalOrientation-15.txt\n";
push @versionInfo, "";
while (<FH>) {
chomp;
@ -738,14 +802,15 @@ sub sprintCharProps2_short
{
my $usv = shift;
return sprintf("{%d,%d},",
$verticalOrientation[$usv], $xidmod[$usv]);
$verticalOrientation[$usv], $idtype[$usv]);
}
$type = q|
struct nsCharProps2 {
// Currently only 6 bits are defined here, so 2 more could be added without
// affecting the storage requirements for this struct.
// Currently only 4 bits are defined here, so 4 more could be added without
// affecting the storage requirements for this struct. Or we could pack two
// records per byte, at the cost of a slightly more complex accessor.
unsigned char mVertOrient:2;
unsigned char mXidmod:4;
unsigned char mIdType:2;
};
|;
&genTables("#if ENABLE_INTL_API", "#endif",
@ -754,23 +819,31 @@ struct nsCharProps2 {
sub sprintCharProps2_full
{
my $usv = shift;
return sprintf("{%d,%d,%d,%d,%d,%d,%d,%d,%d},",
return sprintf("{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d},",
$script[$usv], $pairedBracketType[$usv],
$eastAsianWidthFWH[$usv], $category[$usv],
$bidicategory[$usv], $xidmod[$usv], $numericvalue[$usv],
$verticalOrientation[$usv], $lineBreak[$usv]);
$idtype[$usv], $defaultIgnorable[$usv], $bidicategory[$usv],
$verticalOrientation[$usv], $lineBreak[$usv],
$numericvalue[$usv]);
}
$type = q|
// This struct currently requires 5 bytes. We try to ensure that whole-byte
// fields will not straddle byte boundaries, to optimize access to them.
struct nsCharProps2 {
unsigned char mScriptCode:8;
// -- byte boundary --
unsigned char mPairedBracketType:2;
unsigned char mEastAsianWidthFWH:1;
unsigned char mCategory:5;
// -- byte boundary --
unsigned char mIdType:2;
unsigned char mDefaultIgnorable:1;
unsigned char mBidiCategory:5;
unsigned char mXidmod:4;
signed char mNumericValue:5;
// -- byte boundary --
unsigned char mVertOrient:2;
unsigned char mLineBreak; // only 6 bits actually needed
unsigned char mLineBreak:6;
// -- byte boundary --
signed char mNumericValue; // only 5 bits are actually needed here
};
|;
&genTables("#if !ENABLE_INTL_API", "#endif",

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

@ -56,16 +56,18 @@ GetCharProps2(uint32_t aCh)
static const nsCharProps2 undefined = {
#if ENABLE_INTL_API
VERTICAL_ORIENTATION_R,
XIDMOD_NOT_CHARS
0 // IdentifierType
#else
uint8_t(Script::UNKNOWN),
PAIRED_BRACKET_TYPE_NONE,
0, // EastAsianWidthFWH
HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED,
0, // IdentifierType
0, // DefaultIgnorable
eCharType_LeftToRight,
XIDMOD_NOT_CHARS,
-1, // Numeric Value
VERTICAL_ORIENTATION_R
VERTICAL_ORIENTATION_R,
0, // LineBreak
-1 // Numeric Value
#endif
};
return undefined;
@ -300,6 +302,7 @@ bool IsEastAsianWidthFWH(uint32_t aCh)
{
return GetCharProps2(aCh).mEastAsianWidthFWH;
}
#endif
#define DEFINE_BMP_1PLANE_MAPPING_GET_FUNC(prefix_) \

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

@ -40,20 +40,13 @@ enum PairedBracketType {
PAIRED_BRACKET_TYPE_CLOSE = 2
};
enum XidmodType {
XIDMOD_RECOMMENDED,
XIDMOD_INCLUSION,
XIDMOD_UNCOMMON_USE,
XIDMOD_TECHNICAL,
XIDMOD_OBSOLETE,
XIDMOD_ASPIRATIONAL,
XIDMOD_LIMITED_USE,
XIDMOD_EXCLUSION,
XIDMOD_NOT_XID,
XIDMOD_NOT_NFKC,
XIDMOD_DEFAULT_IGNORABLE,
XIDMOD_DEPRECATED,
XIDMOD_NOT_CHARS
/* Flags for Unicode security IdentifierType.txt attributes. Only a subset
of these are currently checked by Gecko, so we only define flags for the
ones we need. */
enum IdentifierType {
IDTYPE_RESTRICTED = 0,
IDTYPE_ALLOWED = 1,
IDTYPE_ASPIRATIONAL = 2,
};
#if ENABLE_INTL_API // ICU is available, so simply forward to its API
@ -172,6 +165,12 @@ IsEastAsianWidthFWH(uint32_t aCh)
return false;
}
inline bool
IsDefaultIgnorable(uint32_t aCh)
{
return u_hasBinaryProperty(aCh, UCHAR_DEFAULT_IGNORABLE_CODE_POINT);
}
#else // not ENABLE_INTL_API
// Return whether the char has a mirrored-pair counterpart.
@ -211,6 +210,12 @@ uint32_t GetTitlecaseForAll(uint32_t aCh); // maps both UC and LC to titlecase
// Return whether the char has EastAsianWidth class F or W or H.
bool IsEastAsianWidthFWH(uint32_t aCh);
// Return whether the char is default-ignorable.
inline bool IsDefaultIgnorable(uint32_t aCh)
{
return GetCharProps2(aCh).mDefaultIgnorable;
}
#endif // !ENABLE_INTL_API
// returns the simplified Gen Category as defined in nsIUGenCategory
@ -222,8 +227,8 @@ inline VerticalOrientation GetVerticalOrientation(uint32_t aCh) {
return VerticalOrientation(GetCharProps2(aCh).mVertOrient);
}
inline XidmodType GetIdentifierModification(uint32_t aCh) {
return XidmodType(GetCharProps2(aCh).mXidmod);
inline IdentifierType GetIdentifierType(uint32_t aCh) {
return IdentifierType(GetCharProps2(aCh).mIdType);
}
uint32_t GetFullWidth(uint32_t aCh);

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -11,13 +11,13 @@
*/
/*
* Created on Wed Oct 26 09:12:45 2016 from UCD data files with version info:
* Created on Fri Nov 11 17:42:07 2016 from UCD data files with version info:
*
# Date: 2015-06-16, 20:24:00 GMT [KW]
#
# Unicode Character Database
# Copyright (c) 1991-2015 Unicode, Inc.
# Date: 2016-06-20, 14:59:00 GMT [KW]
# © 2016 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# For documentation, see the following:
@ -25,41 +25,44 @@
# UAX #38, "Unicode Han Database (Unihan)"
# UAX #44, "Unicode Character Database."
#
# The UAXes can be accessed at http://www.unicode.org/versions/Unicode8.0.0/
# The UAXes can be accessed at http://www.unicode.org/versions/Unicode9.0.0/
This directory contains the final data files
for the Unicode Character Database, for Version 8.0.0 of the Unicode
Standard.
for the Unicode Character Database, for Version 9.0.0 of the Unicode Standard.
# Scripts-9.0.0.txt
# Date: 2016-06-01, 10:34:37 GMT
# Scripts-8.0.0.txt
# Date: 2015-03-11, 22:29:42 GMT [MD]
# BidiMirroring-9.0.0.txt
# Date: 2016-01-21, 22:00:00 GMT [KW, LI]
# BidiMirroring-8.0.0.txt
# Date: 2015-01-20, 18:30:00 GMT [KW, LI]
# BidiBrackets-9.0.0.txt
# Date: 2016-06-07, 22:30:00 GMT [AG, LI, KW]
# BidiBrackets-8.0.0.txt
# Date: 2015-01-20, 19:00:00 GMT [AG, LI, KW]
# HangulSyllableType-9.0.0.txt
# Date: 2016-03-02, 18:55:01 GMT
# HangulSyllableType-8.0.0.txt
# Date: 2014-12-16, 23:07:45 GMT [MD]
# LineBreak-9.0.0.txt
# Date: 2016-05-26, 01:00:00 GMT [KW, LI]
# LineBreak-8.0.0.txt
# Date: 2015-02-13, 09:15:00 GMT [KW, LI]
# EastAsianWidth-9.0.0.txt
# Date: 2016-05-27, 17:00:00 GMT [KW, LI]
# EastAsianWidth-8.0.0.txt
# Date: 2015-02-10, 21:00:00 GMT [KW, LI]
# DerivedCoreProperties-9.0.0.txt
# Date: 2016-06-01, 10:34:24 GMT
# File: xidmodifications.txt
# Version: 8.0.0
# Generated: 2015-05-17, 03:09:04 GMT
# IdentifierStatus.txt
# Date: 2016-06-16, 13:41:30 GMT
# IdentifierType.txt
# Date: 2016-06-16, 13:41:30 GMT
#
# Unihan_Variants.txt
# Date: 2015-04-30 18:38:20 GMT [JHJ]
# Date: 2016-06-01 07:01:48 GMT [JHJ]
# VerticalOrientation-13.txt
# Date: 2014-09-03, 17:30:00 GMT [EM, KI, LI]
# VerticalOrientation-15.txt
# Date: 2015-11-16, 20:00:00 GMT [EM, KI, LI]
*
* * * * * This file contains MACHINE-GENERATED DATA, do not edit! * * * * *
@ -83,26 +86,34 @@ struct nsCharProps1 {
#if ENABLE_INTL_API
struct nsCharProps2 {
// Currently only 6 bits are defined here, so 2 more could be added without
// affecting the storage requirements for this struct.
// Currently only 4 bits are defined here, so 4 more could be added without
// affecting the storage requirements for this struct. Or we could pack two
// records per byte, at the cost of a slightly more complex accessor.
unsigned char mVertOrient:2;
unsigned char mXidmod:4;
unsigned char mIdType:2;
};
#endif
#if !ENABLE_INTL_API
// This struct currently requires 5 bytes. We try to ensure that whole-byte
// fields will not straddle byte boundaries, to optimize access to them.
struct nsCharProps2 {
unsigned char mScriptCode:8;
// -- byte boundary --
unsigned char mPairedBracketType:2;
unsigned char mEastAsianWidthFWH:1;
unsigned char mCategory:5;
// -- byte boundary --
unsigned char mIdType:2;
unsigned char mDefaultIgnorable:1;
unsigned char mBidiCategory:5;
unsigned char mXidmod:4;
signed char mNumericValue:5;
// -- byte boundary --
unsigned char mVertOrient:2;
unsigned char mLineBreak; // only 6 bits actually needed
unsigned char mLineBreak:6;
// -- byte boundary --
signed char mNumericValue; // only 5 bits are actually needed here
};
#endif
@ -279,8 +290,16 @@ enum class Script {
MULTANI = 164,
PAU_CIN_HAU = 165,
SIDDHAM = 166,
ADLAM = 167,
BHAIKSUKI = 168,
MARCHEN = 169,
NEWA = 170,
OSAGE = 171,
HAN_WITH_BOPOMOFO = 172,
JAMO = 173,
SYMBOLS_EMOJI = 174,
NUM_SCRIPT_CODES = 167,
NUM_SCRIPT_CODES = 175,
INVALID = -1
};

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

@ -70,6 +70,11 @@ ProcessId GetProcId(ProcessHandle process) {
bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
bool result = kill(process_id, SIGTERM) == 0;
if (!result && (errno == ESRCH)) {
result = true;
wait = false;
}
if (result && wait) {
int tries = 60;
bool exited = false;
@ -79,6 +84,9 @@ bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
if (pid == process_id) {
exited = true;
break;
} else if (errno == ECHILD) {
exited = true;
break;
}
sleep(1);

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

@ -147,6 +147,12 @@ class Channel {
// For portability the prefix should not include the \ character.
static std::wstring GenerateVerifiedChannelID(const std::wstring& prefix);
#if defined(MOZ_WIDGET_ANDROID)
// Used to set the first IPC file descriptor in the child process on Android. See
// ipc_channel_posix.cc for further details on how this is used.
static void SetClientChannelFd(int fd);
#endif // defined(MOZ_WIDGET_ANDROID)
private:
// PIMPL to which all channel calls are delegated.
class ChannelImpl;

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

@ -56,9 +56,17 @@ namespace IPC {
//
// When creating a child subprocess, the parent side of the fork
// arranges it such that the initial control channel ends up on the
// magic file descriptor kClientChannelFd in the child. Future
// magic file descriptor gClientChannelFd in the child. Future
// connections (file descriptors) can then be passed via that
// connection via sendmsg().
//
// On Android, child processes are created as a service instead of
// forking the parent process. The Android Binder service is used to
// transport the IPC channel file descriptor to the child process.
// So rather than re-mapping the file descriptor to a known value,
// the received channel file descriptor is set by calling
// SetClientChannelFd before gecko has been initialized and started
// in the child process.
//------------------------------------------------------------------------------
namespace {
@ -66,7 +74,7 @@ namespace {
// The PipeMap class works around this quirk related to unit tests:
//
// When running as a server, we install the client socket in a
// specific file descriptor number (@kClientChannelFd). However, we
// specific file descriptor number (@gClientChannelFd). However, we
// also have to support the case where we are running unittests in the
// same process. (We do not support forking without execing.)
//
@ -74,7 +82,7 @@ namespace {
// The IPC server object will install a mapping in PipeMap from the
// name which it was given to the client pipe. When forking the client, the
// GetClientFileDescriptorMapping will ensure that the socket is installed in
// the magic slot (@kClientChannelFd). The client will search for the
// the magic slot (@gClientChannelFd). The client will search for the
// mapping, but it won't find any since we are in a new process. Thus the
// magic fd number is returned. Once the client connects, the server will
// close its copy of the client socket and remove the mapping.
@ -133,7 +141,14 @@ class PipeMap {
// This is the file descriptor number that a client process expects to find its
// IPC socket.
static const int kClientChannelFd = 3;
static int gClientChannelFd =
#if defined(MOZ_WIDGET_ANDROID)
// On android the fd is set at the time of child creation.
-1
#else
3
#endif // defined(MOZ_WIDGET_ANDROID)
;
// Used to map a channel name to the equivalent FD # in the client process.
int ChannelNameToClientFD(const std::string& channel_id) {
@ -144,7 +159,7 @@ int ChannelNameToClientFD(const std::string& channel_id) {
// If we don't find an entry, we assume that the correct value has been
// inserted in the magic slot.
return kClientChannelFd;
return gClientChannelFd;
}
//------------------------------------------------------------------------------
@ -165,6 +180,12 @@ bool SetCloseOnExec(int fd) {
} // namespace
//------------------------------------------------------------------------------
#if defined(MOZ_WIDGET_ANDROID)
void Channel::SetClientChannelFd(int fd) {
gClientChannelFd = fd;
}
#endif // defined(MOZ_WIDGET_ANDROID)
Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode,
Listener* listener)
: factory_(this) {
@ -175,7 +196,11 @@ Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode,
CHROMIUM_LOG(WARNING) << "Unable to create pipe named \"" << channel_id <<
"\" in " << (mode == MODE_SERVER ? "server" : "client") <<
" mode error(" << strerror(errno) << ").";
closed_ = true;
return;
}
EnqueueHelloMessage();
}
Channel::ChannelImpl::ChannelImpl(int fd, Mode mode, Listener* listener)
@ -248,8 +273,7 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
waiting_connect_ = false;
}
// Create the Hello message to be sent when Connect is called
return EnqueueHelloMessage();
return true;
}
/**
@ -759,7 +783,7 @@ void Channel::ChannelImpl::GetClientFileDescriptorMapping(int *src_fd,
int *dest_fd) const {
DCHECK(mode_ == MODE_SERVER);
*src_fd = client_pipe_;
*dest_fd = kClientChannelFd;
*dest_fd = gClientChannelFd;
}
void Channel::ChannelImpl::CloseClientFileDescriptor() {

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

@ -219,6 +219,7 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
if (pipe_ == INVALID_HANDLE_VALUE) {
// If this process is being closed, the pipe may be gone already.
CHROMIUM_LOG(WARNING) << "failed to create pipe: " << GetLastError();
closed_ = true;
return false;
}

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

@ -60,15 +60,11 @@
using mozilla::MonitorAutoLock;
using mozilla::ipc::GeckoChildProcessHost;
#ifdef ANDROID
// Like its predecessor in nsExceptionHandler.cpp, this is
// the magic number of a file descriptor remapping we must
// preserve for the child process.
static const int kMagicAndroidSystemPropFd = 5;
#endif
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidBridge.h"
#include "GeneratedJNIWrappers.h"
#include "mozilla/jni/Refs.h"
#include "mozilla/jni/Utils.h"
#endif
static const bool kLowRightsSubprocesses =
@ -191,17 +187,7 @@ GeckoChildProcessHost::GetPathToBinary(FilePath& exePath, GeckoProcessType proce
exePath = exePath.DirName();
}
#ifdef MOZ_WIDGET_ANDROID
exePath = exePath.AppendASCII("lib");
// We must use the PIE binary on 5.0 and higher
const char* processName = mozilla::AndroidBridge::Bridge()->GetAPIVersion() >= 21 ?
MOZ_CHILD_PROCESS_NAME_PIE : MOZ_CHILD_PROCESS_NAME;
exePath = exePath.AppendASCII(processName);
#else
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
#endif
return BinaryPathType::PluginContainer;
}
@ -767,9 +753,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
nsCString path;
NS_CopyUnicodeToNative(nsDependentString(gGREBinPath), path);
# if defined(OS_LINUX) || defined(OS_BSD)
# if defined(MOZ_WIDGET_ANDROID)
path += "/lib";
# endif // MOZ_WIDGET_ANDROID
const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH");
nsCString new_ld_lib_path(path.get());
@ -813,28 +796,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
FilePath exePath;
BinaryPathType pathType = GetPathToBinary(exePath, mProcessType);
#ifdef MOZ_WIDGET_ANDROID
// The java wrapper unpacks this for us but can't make it executable
chmod(exePath.value().c_str(), 0700);
#endif // MOZ_WIDGET_ANDROID
#ifdef ANDROID
// Remap the Android property workspace to a well-known int,
// and update the environment to reflect the new value for the
// child process.
const char *apws = getenv("ANDROID_PROPERTY_WORKSPACE");
if (apws) {
int fd = atoi(apws);
mFileMap.push_back(std::pair<int, int>(fd, kMagicAndroidSystemPropFd));
char buf[32];
char *szptr = strchr(apws, ',');
snprintf(buf, sizeof(buf), "%d%s", kMagicAndroidSystemPropFd, szptr);
newEnvVars["ANDROID_PROPERTY_WORKSPACE"] = buf;
}
#endif // ANDROID
#ifdef MOZ_WIDGET_GONK
if (const char *ldPreloadPath = getenv("LD_PRELOAD")) {
newEnvVars["LD_PRELOAD"] = ldPreloadPath;
@ -935,11 +896,15 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
childArgv.push_back(childProcessType);
#if defined(MOZ_WIDGET_ANDROID)
LaunchAndroidService(childProcessType, childArgv, mFileMap, &process);
#else
base::LaunchApp(childArgv, mFileMap,
#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD)
newEnvVars, privs,
#endif
false, &process, arch);
#endif // defined(MOZ_WIDGET_ANDROID)
// We're in the parent and the child was launched. Close the child FD in the
// parent as soon as possible, which will allow the parent to detect when the
@ -1266,3 +1231,32 @@ GeckoChildProcessHost::GetQueuedMessages(std::queue<IPC::Message>& queue)
}
bool GeckoChildProcessHost::sRunSelfAsContentProc(false);
#ifdef MOZ_WIDGET_ANDROID
void
GeckoChildProcessHost::LaunchAndroidService(const char* type,
const std::vector<std::string>& argv,
const base::file_handle_mapping_vector& fds_to_remap,
ProcessHandle* process_handle)
{
MOZ_ASSERT((fds_to_remap.size() > 0) && (fds_to_remap.size() <= 2));
JNIEnv* env = mozilla::jni::GetEnvForThread();
MOZ_ASSERT(env);
int argvSize = argv.size();
jni::ObjectArray::LocalRef jargs = jni::ObjectArray::LocalRef::Adopt(env->NewObjectArray(argvSize, env->FindClass("java/lang/String"), nullptr));
for (int ix = 0; ix < argvSize; ix++) {
jargs->SetElement(ix, jni::StringParam(argv[ix].c_str(), env));
}
base::file_handle_mapping_vector::const_iterator it = fds_to_remap.begin();
int32_t ipcFd = it->first;
it++;
// If the Crash Reporter is disabled, there will not be a second file descriptor.
int32_t crashFd = (it != fds_to_remap.end()) ? it->first : -1;
int32_t handle = java::GeckoAppShell::StartGeckoServiceChildProcess(type, jargs, crashFd, ipcFd);
if (process_handle) {
*process_handle = handle;
}
}
#endif

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