зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
8cfa5253e8
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче