зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound.
This commit is contained in:
Коммит
fc23b85416
|
@ -691,6 +691,8 @@ getRoleCB(AtkObject *aAtkObj)
|
||||||
|
|
||||||
if (aAtkObj->role == ATK_ROLE_LIST_BOX && !IsAtkVersionAtLeast(2, 1))
|
if (aAtkObj->role == ATK_ROLE_LIST_BOX && !IsAtkVersionAtLeast(2, 1))
|
||||||
aAtkObj->role = ATK_ROLE_LIST;
|
aAtkObj->role = ATK_ROLE_LIST;
|
||||||
|
else if (aAtkObj->role == ATK_ROLE_TABLE_ROW && !IsAtkVersionAtLeast(2, 1))
|
||||||
|
aAtkObj->role = ATK_ROLE_LIST_ITEM;
|
||||||
|
|
||||||
return aAtkObj->role;
|
return aAtkObj->role;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ extern int atkMajorVersion, atkMinorVersion;
|
||||||
static inline bool
|
static inline bool
|
||||||
IsAtkVersionAtLeast(int aMajor, int aMinor)
|
IsAtkVersionAtLeast(int aMajor, int aMinor)
|
||||||
{
|
{
|
||||||
return aMajor < atkMajorVersion && aMinor < atkMinorVersion;
|
return aMajor < atkMajorVersion ||
|
||||||
|
(aMajor == atkMajorVersion && aMinor <= atkMinorVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __NS_MAI_H__ */
|
#endif /* __NS_MAI_H__ */
|
||||||
|
|
|
@ -242,7 +242,7 @@ ROLE(COLUMN,
|
||||||
|
|
||||||
ROLE(ROW,
|
ROLE(ROW,
|
||||||
"row",
|
"row",
|
||||||
ATK_ROLE_LIST_ITEM,
|
ATK_ROLE_TABLE_ROW,
|
||||||
NSAccessibilityRowRole,
|
NSAccessibilityRowRole,
|
||||||
ROLE_SYSTEM_ROW,
|
ROLE_SYSTEM_ROW,
|
||||||
ROLE_SYSTEM_ROW,
|
ROLE_SYSTEM_ROW,
|
||||||
|
|
|
@ -168,7 +168,7 @@ if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
|
||||||
WINNT)
|
WINNT)
|
||||||
ICU_TARGET=MSYS/MSVC
|
ICU_TARGET=MSYS/MSVC
|
||||||
;;
|
;;
|
||||||
*bsd*|dragonfly*)
|
DragonFly|FreeBSD|NetBSD|OpenBSD|GNU_kFreeBSD)
|
||||||
ICU_TARGET=BSD
|
ICU_TARGET=BSD
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
18
configure.in
18
configure.in
|
@ -1023,6 +1023,24 @@ darwin*)
|
||||||
linux*)
|
linux*)
|
||||||
HOST_OS_ARCH=Linux
|
HOST_OS_ARCH=Linux
|
||||||
;;
|
;;
|
||||||
|
kfreebsd*-gnu)
|
||||||
|
HOST_OS_ARCH=GNU_kFreeBSD
|
||||||
|
;;
|
||||||
|
gnu*)
|
||||||
|
HOST_OS_ARCH=GNU
|
||||||
|
;;
|
||||||
|
dragonfly*)
|
||||||
|
HOST_OS_ARCH=DragonFly
|
||||||
|
;;
|
||||||
|
freebsd*)
|
||||||
|
HOST_OS_ARCH=FreeBSD
|
||||||
|
;;
|
||||||
|
netbsd*)
|
||||||
|
HOST_OS_ARCH=NetBSD
|
||||||
|
;;
|
||||||
|
openbsd*)
|
||||||
|
HOST_OS_ARCH=OpenBSD
|
||||||
|
;;
|
||||||
solaris*)
|
solaris*)
|
||||||
HOST_OS_ARCH=SunOS
|
HOST_OS_ARCH=SunOS
|
||||||
SOLARIS_SUNPRO_CC=
|
SOLARIS_SUNPRO_CC=
|
||||||
|
|
|
@ -457,7 +457,7 @@ nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, mPendingScripts.Length(), nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, mPendingScripts.Length()));
|
||||||
NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
JS::Rooted<JSString*> url(aCx);
|
JS::Rooted<JSString*> url(aCx);
|
||||||
|
@ -466,10 +466,11 @@ nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<
|
||||||
url = JS_NewUCStringCopyN(aCx, mPendingScripts[i].get(), mPendingScripts[i].Length());
|
url = JS_NewUCStringCopyN(aCx, mPendingScripts[i].get(), mPendingScripts[i].Length());
|
||||||
NS_ENSURE_TRUE(url, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(url, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
JS::Value pairElts[] = { JS::StringValue(url),
|
JS::AutoValueArray<2> pairElts(aCx);
|
||||||
JS::BooleanValue(mPendingScriptsGlobalStates[i]) };
|
pairElts[0].setString(url);
|
||||||
|
pairElts[1].setBoolean(mPendingScriptsGlobalStates[i]);
|
||||||
|
|
||||||
pair = JS_NewArrayObject(aCx, 2, pairElts);
|
pair = JS_NewArrayObject(aCx, pairElts);
|
||||||
NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, pair),
|
NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, pair),
|
||||||
|
@ -598,7 +599,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t len = retval.Length();
|
uint32_t len = retval.Length();
|
||||||
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len));
|
||||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; ++i) {
|
for (uint32_t i = 0; i < len; ++i) {
|
||||||
|
|
|
@ -1245,14 +1245,13 @@ CanvasRenderingContext2D::SetTransform(double m11, double m12,
|
||||||
JSObject*
|
JSObject*
|
||||||
MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
|
MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
|
||||||
{
|
{
|
||||||
JS::Value elts[] = {
|
JS::AutoValueArray<6> elts(cx);
|
||||||
DOUBLE_TO_JSVAL(matrix._11), DOUBLE_TO_JSVAL(matrix._12),
|
elts[0].setDouble(matrix._11); elts[1].setDouble(matrix._12);
|
||||||
DOUBLE_TO_JSVAL(matrix._21), DOUBLE_TO_JSVAL(matrix._22),
|
elts[2].setDouble(matrix._21); elts[3].setDouble(matrix._22);
|
||||||
DOUBLE_TO_JSVAL(matrix._31), DOUBLE_TO_JSVAL(matrix._32)
|
elts[4].setDouble(matrix._31); elts[5].setDouble(matrix._32);
|
||||||
};
|
|
||||||
|
|
||||||
// XXX Should we enter GetWrapper()'s compartment?
|
// XXX Should we enter GetWrapper()'s compartment?
|
||||||
JSObject* obj = JS_NewArrayObject(cx, 6, elts);
|
JSObject* obj = JS_NewArrayObject(cx, elts);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
error.Throw(NS_ERROR_OUT_OF_MEMORY);
|
error.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ DashArrayToJSVal(FallibleTArray<T>& dashes,
|
||||||
return JSVAL_NULL;
|
return JSVAL_NULL;
|
||||||
}
|
}
|
||||||
JS::Rooted<JSObject*> obj(cx,
|
JS::Rooted<JSObject*> obj(cx,
|
||||||
JS_NewArrayObject(cx, dashes.Length(), nullptr));
|
JS_NewArrayObject(cx, dashes.Length()));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
return JSVAL_NULL;
|
return JSVAL_NULL;
|
||||||
|
|
|
@ -1907,10 +1907,10 @@ WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog,
|
||||||
if (unitSize == 1) {
|
if (unitSize == 1) {
|
||||||
return JS::BooleanValue(iv[0] ? true : false);
|
return JS::BooleanValue(iv[0] ? true : false);
|
||||||
} else {
|
} else {
|
||||||
JS::Value uv[16];
|
JS::AutoValueArray<16> uv(cx);
|
||||||
for (int k = 0; k < unitSize; k++)
|
for (int k = 0; k < unitSize; k++)
|
||||||
uv[k] = JS::BooleanValue(iv[k] ? true : false);
|
uv[k].setBoolean(iv[k]);
|
||||||
JSObject* obj = JS_NewArrayObject(cx, unitSize, uv);
|
JSObject* obj = JS_NewArrayObject(cx, JS::HandleValueArray::subarray(uv, 0, unitSize));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
ErrorOutOfMemory("getUniform: out of memory");
|
ErrorOutOfMemory("getUniform: out of memory");
|
||||||
return JS::NullValue();
|
return JS::NullValue();
|
||||||
|
|
|
@ -423,11 +423,12 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
||||||
{
|
{
|
||||||
realGLboolean gl_bv[4] = { 0 };
|
realGLboolean gl_bv[4] = { 0 };
|
||||||
gl->fGetBooleanv(pname, gl_bv);
|
gl->fGetBooleanv(pname, gl_bv);
|
||||||
JS::Value vals[4] = { JS::BooleanValue(bool(gl_bv[0])),
|
JS::AutoValueArray<4> vals(cx);
|
||||||
JS::BooleanValue(bool(gl_bv[1])),
|
vals[0].setBoolean(gl_bv[0]);
|
||||||
JS::BooleanValue(bool(gl_bv[2])),
|
vals[1].setBoolean(gl_bv[1]);
|
||||||
JS::BooleanValue(bool(gl_bv[3])) };
|
vals[2].setBoolean(gl_bv[2]);
|
||||||
JSObject* obj = JS_NewArrayObject(cx, 4, vals);
|
vals[3].setBoolean(gl_bv[3]);
|
||||||
|
JSObject* obj = JS_NewArrayObject(cx, vals);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "SampleSink.h"
|
#include "SampleSink.h"
|
||||||
#include "prlog.h"
|
#include "prlog.h"
|
||||||
|
|
||||||
#include <initguid.h>
|
|
||||||
#include <wmsdkidl.h>
|
#include <wmsdkidl.h>
|
||||||
|
|
||||||
using namespace mozilla::media;
|
using namespace mozilla::media;
|
||||||
|
|
|
@ -13,7 +13,6 @@ EXPORTS += [
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'AudioSinkFilter.cpp',
|
|
||||||
'AudioSinkInputPin.cpp',
|
'AudioSinkInputPin.cpp',
|
||||||
'DirectShowDecoder.cpp',
|
'DirectShowDecoder.cpp',
|
||||||
'DirectShowReader.cpp',
|
'DirectShowReader.cpp',
|
||||||
|
@ -22,6 +21,10 @@ UNIFIED_SOURCES += [
|
||||||
'SourceFilter.cpp',
|
'SourceFilter.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SOURCES += [
|
||||||
|
'AudioSinkFilter.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
|
# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
|
||||||
# they're available at link time.
|
# they're available at link time.
|
||||||
if not CONFIG['MOZ_WEBRTC']:
|
if not CONFIG['MOZ_WEBRTC']:
|
||||||
|
|
|
@ -29,7 +29,6 @@ which makes Windows Media Foundation unavailable.
|
||||||
#include <mferror.h>
|
#include <mferror.h>
|
||||||
#include <propvarutil.h>
|
#include <propvarutil.h>
|
||||||
#include <wmcodecdsp.h>
|
#include <wmcodecdsp.h>
|
||||||
#include <initguid.h>
|
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include <dxva2api.h>
|
#include <dxva2api.h>
|
||||||
#include <wmcodecdsp.h>
|
#include <wmcodecdsp.h>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "nsWindowsHelpers.h"
|
#include "nsWindowsHelpers.h"
|
||||||
#include "mozilla/CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "VideoUtils.h"
|
#include "VideoUtils.h"
|
||||||
|
#include <initguid.h>
|
||||||
|
|
||||||
#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
|
#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
|
||||||
// Some SDK versions don't define the AAC decoder CLSID.
|
// Some SDK versions don't define the AAC decoder CLSID.
|
||||||
|
|
|
@ -18,6 +18,9 @@ UNIFIED_SOURCES += [
|
||||||
'WMFDecoder.cpp',
|
'WMFDecoder.cpp',
|
||||||
'WMFReader.cpp',
|
'WMFReader.cpp',
|
||||||
'WMFSourceReaderCallback.cpp',
|
'WMFSourceReaderCallback.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
SOURCES += [
|
||||||
'WMFUtils.cpp',
|
'WMFUtils.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -372,9 +372,15 @@ MessagePort::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
if (aTransferable.WasPassed()) {
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
||||||
|
|
||||||
|
// The input sequence only comes from the generated bindings code, which
|
||||||
|
// ensures it is rooted.
|
||||||
|
JS::HandleValueArray elements =
|
||||||
|
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
||||||
|
realTransferable.Elements());
|
||||||
|
|
||||||
JSObject* array =
|
JSObject* array =
|
||||||
JS_NewArrayObject(aCx, realTransferable.Length(),
|
JS_NewArrayObject(aCx, elements);
|
||||||
const_cast<JS::Value*>(realTransferable.Elements()));
|
|
||||||
if (!array) {
|
if (!array) {
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7940,9 +7940,13 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
||||||
if (aTransfer.WasPassed()) {
|
if (aTransfer.WasPassed()) {
|
||||||
const Sequence<JS::Value >& values = aTransfer.Value();
|
const Sequence<JS::Value >& values = aTransfer.Value();
|
||||||
transferArray = JS::ObjectOrNullValue(JS_NewArrayObject(aCx,
|
|
||||||
values.Length(),
|
// The input sequence only comes from the generated bindings code, which
|
||||||
const_cast<JS::Value*>(values.Elements())));
|
// ensures it is rooted.
|
||||||
|
JS::HandleValueArray elements =
|
||||||
|
JS::HandleValueArray::fromMarkedLocation(values.Length(), values.Elements());
|
||||||
|
|
||||||
|
transferArray = JS::ObjectOrNullValue(JS_NewArrayObject(aCx, elements));
|
||||||
if (transferArray.isNull()) {
|
if (transferArray.isNull()) {
|
||||||
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
|
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1169,7 +1169,7 @@ nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject* array = ::JS_NewArrayObject(mContext, args.length(), args.begin());
|
JSObject* array = ::JS_NewArrayObject(mContext, args);
|
||||||
if (!array) {
|
if (!array) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4428,7 +4428,7 @@ if (%s.IsNull()) {
|
||||||
innerTemplate = CGIndenter(CGGeneric(innerTemplate), 6).define()
|
innerTemplate = CGIndenter(CGGeneric(innerTemplate), 6).define()
|
||||||
return (("""
|
return (("""
|
||||||
uint32_t length = %s.Length();
|
uint32_t length = %s.Length();
|
||||||
JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length, nullptr));
|
JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
|
||||||
if (!returnArray) {
|
if (!returnArray) {
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ CameraControlImpl::Get(JSContext* aCx, uint32_t aKey, JS::Value* aValue)
|
||||||
|
|
||||||
GetParameter(aKey, regionArray);
|
GetParameter(aKey, regionArray);
|
||||||
|
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ DOMCameraCapabilities::ParameterListToNewArray(JSContext* aCx,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
aArray.set(JS_NewArrayObject(aCx, 0, nullptr));
|
aArray.set(JS_NewArrayObject(aCx, 0));
|
||||||
if (!aArray) {
|
if (!aArray) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::MutableHandle<JS::Value>
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, 0, nullptr));
|
JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
#include "nsIEditor.h"
|
||||||
#include "nsIMEStateManager.h"
|
#include "nsIMEStateManager.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
|
@ -27,7 +28,8 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||||
mPresContext(aPresContext), mNode(aNode),
|
mPresContext(aPresContext), mNode(aNode),
|
||||||
mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext),
|
mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext),
|
||||||
mCompositionStartOffset(0), mCompositionTargetOffset(0),
|
mCompositionStartOffset(0), mCompositionTargetOffset(0),
|
||||||
mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests)
|
mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests),
|
||||||
|
mIsComposing(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +51,20 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||||
nsEventDispatcher::Dispatch(mNode, mPresContext,
|
nsEventDispatcher::Dispatch(mNode, mPresContext,
|
||||||
aEvent, nullptr, aStatus, aCallBack);
|
aEvent, nullptr, aStatus, aCallBack);
|
||||||
|
|
||||||
|
// Emulate editor behavior of text event handler if no editor handles
|
||||||
|
// composition/text events.
|
||||||
|
if (aEvent->message == NS_TEXT_TEXT && !HasEditor()) {
|
||||||
|
EditorWillHandleTextEvent(aEvent->AsTextEvent());
|
||||||
|
EditorDidHandleTextEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
else if (aEvent->message == NS_COMPOSITION_END) {
|
||||||
|
MOZ_ASSERT(!mIsComposing, "Why is the editor still composing?");
|
||||||
|
MOZ_ASSERT(!HasEditor(), "Why does the editor still keep to hold this?");
|
||||||
|
}
|
||||||
|
#endif // #ifdef DEBUG
|
||||||
|
|
||||||
// Notify composition update to widget if possible
|
// Notify composition update to widget if possible
|
||||||
NotityUpdateComposition(aEvent);
|
NotityUpdateComposition(aEvent);
|
||||||
}
|
}
|
||||||
|
@ -123,6 +139,53 @@ TextComposition::NotifyIME(widget::NotificationToIME aNotification)
|
||||||
return nsIMEStateManager::NotifyIME(aNotification, mPresContext);
|
return nsIMEStateManager::NotifyIME(aNotification, mPresContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent)
|
||||||
|
{
|
||||||
|
mIsComposing = aTextEvent->IsComposing();
|
||||||
|
|
||||||
|
MOZ_ASSERT(mLastData == aTextEvent->theText,
|
||||||
|
"The text of a text event must be same as previous data attribute value "
|
||||||
|
"of the latest compositionupdate event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TextComposition::EditorDidHandleTextEvent()
|
||||||
|
{
|
||||||
|
mString = mLastData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TextComposition::StartHandlingComposition(nsIEditor* aEditor)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!HasEditor(), "There is a handling editor already");
|
||||||
|
mEditorWeak = do_GetWeakReference(aEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TextComposition::EndHandlingComposition(nsIEditor* aEditor)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||||
|
MOZ_ASSERT(editor == aEditor, "Another editor handled the composition?");
|
||||||
|
#endif // #ifdef DEBUG
|
||||||
|
mEditorWeak = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIEditor>
|
||||||
|
TextComposition::GetEditor() const
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIEditor> editor = do_QueryReferent(mEditorWeak);
|
||||||
|
return editor.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TextComposition::HasEditor() const
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||||
|
return !!editor;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TextComposition::CompositionEventDispatcher
|
* TextComposition::CompositionEventDispatcher
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
|
#include "nsIWeakReference.h"
|
||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
@ -17,8 +18,8 @@
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
|
|
||||||
class nsDispatchingCallback;
|
class nsDispatchingCallback;
|
||||||
|
class nsIEditor;
|
||||||
class nsIMEStateManager;
|
class nsIMEStateManager;
|
||||||
class nsIWidget;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -47,7 +48,14 @@ public:
|
||||||
nsPresContext* GetPresContext() const { return mPresContext; }
|
nsPresContext* GetPresContext() const { return mPresContext; }
|
||||||
nsINode* GetEventTargetNode() const { return mNode; }
|
nsINode* GetEventTargetNode() const { return mNode; }
|
||||||
// The latest CompositionEvent.data value except compositionstart event.
|
// The latest CompositionEvent.data value except compositionstart event.
|
||||||
const nsString& GetLastData() const { return mLastData; }
|
// This value is modified at dispatching compositionupdate.
|
||||||
|
const nsString& LastData() const { return mLastData; }
|
||||||
|
// The composition string which is already handled by the focused editor.
|
||||||
|
// I.e., this value must be same as the composition string on the focused
|
||||||
|
// editor. This value is modified at a call of EditorDidHandleTextEvent().
|
||||||
|
// Note that mString and mLastData are different between dispatcing
|
||||||
|
// compositionupdate and text event handled by focused editor.
|
||||||
|
const nsString& String() const { return mString; }
|
||||||
// Returns true if the composition is started with synthesized event which
|
// Returns true if the composition is started with synthesized event which
|
||||||
// came from nsDOMWindowUtils.
|
// came from nsDOMWindowUtils.
|
||||||
bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
|
bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
|
||||||
|
@ -73,6 +81,45 @@ public:
|
||||||
*/
|
*/
|
||||||
uint32_t OffsetOfTargetClause() const { return mCompositionTargetOffset; }
|
uint32_t OffsetOfTargetClause() const { return mCompositionTargetOffset; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there is non-empty composition string and it's not fixed.
|
||||||
|
* Otherwise, false.
|
||||||
|
*/
|
||||||
|
bool IsComposing() const { return mIsComposing; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StartHandlingComposition() and EndHandlingComposition() are called by
|
||||||
|
* editor when it holds a TextComposition instance and release it.
|
||||||
|
*/
|
||||||
|
void StartHandlingComposition(nsIEditor* aEditor);
|
||||||
|
void EndHandlingComposition(nsIEditor* aEditor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextEventHandlingMarker class should be created at starting to handle text
|
||||||
|
* event in focused editor. This calls EditorWillHandleTextEvent() and
|
||||||
|
* EditorDidHandleTextEvent() automatically.
|
||||||
|
*/
|
||||||
|
class MOZ_STACK_CLASS TextEventHandlingMarker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextEventHandlingMarker(TextComposition* aComposition,
|
||||||
|
const WidgetTextEvent* aTextEvent)
|
||||||
|
: mComposition(aComposition)
|
||||||
|
{
|
||||||
|
mComposition->EditorWillHandleTextEvent(aTextEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
~TextEventHandlingMarker()
|
||||||
|
{
|
||||||
|
mComposition->EditorDidHandleTextEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<TextComposition> mComposition;
|
||||||
|
TextEventHandlingMarker();
|
||||||
|
TextEventHandlingMarker(const TextEventHandlingMarker& aOther);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This class holds nsPresContext weak. This instance shouldn't block
|
// This class holds nsPresContext weak. This instance shouldn't block
|
||||||
// destroying it. When the presContext is being destroyed, it's notified to
|
// destroying it. When the presContext is being destroyed, it's notified to
|
||||||
|
@ -85,10 +132,17 @@ private:
|
||||||
// composition. Don't access the instance, it may not be available.
|
// composition. Don't access the instance, it may not be available.
|
||||||
void* mNativeContext;
|
void* mNativeContext;
|
||||||
|
|
||||||
|
// mEditorWeak is a weak reference to the focused editor handling composition.
|
||||||
|
nsWeakPtr mEditorWeak;
|
||||||
|
|
||||||
// mLastData stores the data attribute of the latest composition event (except
|
// mLastData stores the data attribute of the latest composition event (except
|
||||||
// the compositionstart event).
|
// the compositionstart event).
|
||||||
nsString mLastData;
|
nsString mLastData;
|
||||||
|
|
||||||
|
// mString stores the composition text which has been handled by the focused
|
||||||
|
// editor.
|
||||||
|
nsString mString;
|
||||||
|
|
||||||
// Offset of the composition string from start of the editor
|
// Offset of the composition string from start of the editor
|
||||||
uint32_t mCompositionStartOffset;
|
uint32_t mCompositionStartOffset;
|
||||||
// Offset of the selected clause of the composition string from start of the
|
// Offset of the selected clause of the composition string from start of the
|
||||||
|
@ -98,10 +152,35 @@ private:
|
||||||
// See the comment for IsSynthesizedForTests().
|
// See the comment for IsSynthesizedForTests().
|
||||||
bool mIsSynthesizedForTests;
|
bool mIsSynthesizedForTests;
|
||||||
|
|
||||||
|
// See the comment for IsComposing().
|
||||||
|
bool mIsComposing;
|
||||||
|
|
||||||
// Hide the default constructor and copy constructor.
|
// Hide the default constructor and copy constructor.
|
||||||
TextComposition() {}
|
TextComposition() {}
|
||||||
TextComposition(const TextComposition& aOther);
|
TextComposition(const TextComposition& aOther);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetEditor() returns nsIEditor pointer of mEditorWeak.
|
||||||
|
*/
|
||||||
|
already_AddRefed<nsIEditor> GetEditor() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasEditor() returns true if mEditorWeak holds nsIEditor instance which is
|
||||||
|
* alive. Otherwise, false.
|
||||||
|
*/
|
||||||
|
bool HasEditor() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EditorWillHandleTextEvent() must be called before the focused editor
|
||||||
|
* handles the text event.
|
||||||
|
*/
|
||||||
|
void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EditorDidHandleTextEvent() must be called after the focused editor handles
|
||||||
|
* a text event.
|
||||||
|
*/
|
||||||
|
void EditorDidHandleTextEvent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DispatchEvent() dispatches the aEvent to the mContent synchronously.
|
* DispatchEvent() dispatches the aEvent to the mContent synchronously.
|
||||||
|
|
|
@ -617,9 +617,9 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||||
case REQUEST_TO_COMMIT_COMPOSITION: {
|
case REQUEST_TO_COMMIT_COMPOSITION: {
|
||||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
if (!composition->GetLastData().IsEmpty()) {
|
if (!composition->LastData().IsEmpty()) {
|
||||||
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
||||||
textEvent.theText = composition->GetLastData();
|
textEvent.theText = composition->LastData();
|
||||||
textEvent.mFlags.mIsSynthesizedForTests = true;
|
textEvent.mFlags.mIsSynthesizedForTests = true;
|
||||||
widget->DispatchEvent(&textEvent, status);
|
widget->DispatchEvent(&textEvent, status);
|
||||||
if (widget->Destroyed()) {
|
if (widget->Destroyed()) {
|
||||||
|
@ -629,7 +629,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||||
|
|
||||||
status = nsEventStatus_eIgnore;
|
status = nsEventStatus_eIgnore;
|
||||||
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
||||||
endEvent.data = composition->GetLastData();
|
endEvent.data = composition->LastData();
|
||||||
endEvent.mFlags.mIsSynthesizedForTests = true;
|
endEvent.mFlags.mIsSynthesizedForTests = true;
|
||||||
widget->DispatchEvent(&endEvent, status);
|
widget->DispatchEvent(&endEvent, status);
|
||||||
|
|
||||||
|
@ -638,9 +638,9 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||||
case REQUEST_TO_CANCEL_COMPOSITION: {
|
case REQUEST_TO_CANCEL_COMPOSITION: {
|
||||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
if (!composition->GetLastData().IsEmpty()) {
|
if (!composition->LastData().IsEmpty()) {
|
||||||
WidgetCompositionEvent updateEvent(true, NS_COMPOSITION_UPDATE, widget);
|
WidgetCompositionEvent updateEvent(true, NS_COMPOSITION_UPDATE, widget);
|
||||||
updateEvent.data = composition->GetLastData();
|
updateEvent.data = composition->LastData();
|
||||||
updateEvent.mFlags.mIsSynthesizedForTests = true;
|
updateEvent.mFlags.mIsSynthesizedForTests = true;
|
||||||
widget->DispatchEvent(&updateEvent, status);
|
widget->DispatchEvent(&updateEvent, status);
|
||||||
if (widget->Destroyed()) {
|
if (widget->Destroyed()) {
|
||||||
|
@ -649,7 +649,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||||
|
|
||||||
status = nsEventStatus_eIgnore;
|
status = nsEventStatus_eIgnore;
|
||||||
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
||||||
textEvent.theText = composition->GetLastData();
|
textEvent.theText = composition->LastData();
|
||||||
textEvent.mFlags.mIsSynthesizedForTests = true;
|
textEvent.mFlags.mIsSynthesizedForTests = true;
|
||||||
widget->DispatchEvent(&textEvent, status);
|
widget->DispatchEvent(&textEvent, status);
|
||||||
if (widget->Destroyed()) {
|
if (widget->Destroyed()) {
|
||||||
|
@ -659,7 +659,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||||
|
|
||||||
status = nsEventStatus_eIgnore;
|
status = nsEventStatus_eIgnore;
|
||||||
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
||||||
endEvent.data = composition->GetLastData();
|
endEvent.data = composition->LastData();
|
||||||
endEvent.mFlags.mIsSynthesizedForTests = true;
|
endEvent.mFlags.mIsSynthesizedForTests = true;
|
||||||
widget->DispatchEvent(&endEvent, status);
|
widget->DispatchEvent(&endEvent, status);
|
||||||
|
|
||||||
|
@ -1126,9 +1126,23 @@ nsIMEStateManager::GetFocusSelectionAndRoot(nsISelection** aSel,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextComposition*
|
// static
|
||||||
|
already_AddRefed<TextComposition>
|
||||||
nsIMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
|
nsIMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
|
||||||
{
|
{
|
||||||
return sTextCompositions ?
|
if (!sTextCompositions) {
|
||||||
sTextCompositions->GetCompositionFor(aWidget) : nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
nsRefPtr<TextComposition> textComposition =
|
||||||
|
sTextCompositions->GetCompositionFor(aWidget);
|
||||||
|
return textComposition.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<TextComposition>
|
||||||
|
nsIMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent(),
|
||||||
|
"aEvent has to be WidgetCompositionEvent or WidgetTextEvent");
|
||||||
|
return GetTextCompositionFor(aEvent->widget);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,17 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get TextComposition from widget.
|
* Get TextComposition from widget.
|
||||||
*/
|
*/
|
||||||
static mozilla::TextComposition* GetTextCompositionFor(nsIWidget* aWidget);
|
static already_AddRefed<mozilla::TextComposition>
|
||||||
|
GetTextCompositionFor(nsIWidget* aWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TextComposition instance for the event.
|
||||||
|
*
|
||||||
|
* @param aEvent Should be a composition event or a text event which is
|
||||||
|
* being dispatched.
|
||||||
|
*/
|
||||||
|
static already_AddRefed<mozilla::TextComposition>
|
||||||
|
GetTextCompositionFor(mozilla::WidgetGUIEvent* aEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a notification to IME. It depends on the IME or platform spec what
|
* Send a notification to IME. It depends on the IME or platform spec what
|
||||||
|
|
|
@ -174,7 +174,7 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||||
JS::Value* aValue,
|
JS::Value* aValue,
|
||||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length(), nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length()));
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (!array) {
|
if (!array) {
|
||||||
|
@ -232,7 +232,7 @@ ArchiveRequest::GetFilesResult(JSContext* aCx,
|
||||||
JS::MutableHandle<JS::Value> aValue,
|
JS::MutableHandle<JS::Value> aValue,
|
||||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length(), nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length()));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ ConvertCloneReadInfosToArrayInternal(
|
||||||
nsTArray<StructuredCloneReadInfo>& aReadInfos,
|
nsTArray<StructuredCloneReadInfo>& aReadInfos,
|
||||||
JS::MutableHandle<JS::Value> aResult)
|
JS::MutableHandle<JS::Value> aResult)
|
||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
IDB_WARNING("Failed to make array!");
|
IDB_WARNING("Failed to make array!");
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
|
|
@ -1447,7 +1447,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||||
nsTArray<Key> keys;
|
nsTArray<Key> keys;
|
||||||
mKeys.SwapElements(keys);
|
mKeys.SwapElements(keys);
|
||||||
|
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
IDB_WARNING("Failed to make array!");
|
IDB_WARNING("Failed to make array!");
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
|
|
@ -4931,7 +4931,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||||
nsTArray<Key> keys;
|
nsTArray<Key> keys;
|
||||||
mKeys.SwapElements(keys);
|
mKeys.SwapElements(keys);
|
||||||
|
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
IDB_WARNING("Failed to make array!");
|
IDB_WARNING("Failed to make array!");
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
|
|
@ -191,7 +191,7 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
|
||||||
NS_ENSURE_TRUE(aRecursionDepth < MaxRecursionDepth, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
|
NS_ENSURE_TRUE(aRecursionDepth < MaxRecursionDepth, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
|
||||||
|
|
||||||
if (*aPos - aTypeOffset >= eArray) {
|
if (*aPos - aTypeOffset >= eArray) {
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
NS_WARNING("Failed to make array!");
|
NS_WARNING("Failed to make array!");
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
|
|
|
@ -389,7 +389,7 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t len = mStrings.Length();
|
const uint32_t len = mStrings.Length();
|
||||||
JS::Rooted<JSObject*> arrayObj(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
JS::Rooted<JSObject*> arrayObj(aCx, JS_NewArrayObject(aCx, len));
|
||||||
if (!arrayObj) {
|
if (!arrayObj) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ KeyPath::ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aValue) const
|
||||||
{
|
{
|
||||||
if (IsArray()) {
|
if (IsArray()) {
|
||||||
uint32_t len = mStrings.Length();
|
uint32_t len = mStrings.Length();
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, len));
|
||||||
if (!array) {
|
if (!array) {
|
||||||
IDB_WARNING("Failed to make array!");
|
IDB_WARNING("Failed to make array!");
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
|
|
@ -483,7 +483,7 @@ MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aDelive
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> deliveryInfo(
|
JS::Rooted<JSObject*> deliveryInfo(
|
||||||
aCx, JS_NewArrayObject(aCx, length, nullptr));
|
aCx, JS_NewArrayObject(aCx, length));
|
||||||
NS_ENSURE_TRUE(deliveryInfo, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(deliveryInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
|
@ -614,7 +614,7 @@ MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachm
|
||||||
uint32_t length = mAttachments.Length();
|
uint32_t length = mAttachments.Length();
|
||||||
|
|
||||||
JS::Rooted<JSObject*> attachments(
|
JS::Rooted<JSObject*> attachments(
|
||||||
aCx, JS_NewArrayObject(aCx, length, nullptr));
|
aCx, JS_NewArrayObject(aCx, length));
|
||||||
NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(attachments, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
|
|
|
@ -167,7 +167,7 @@ MobileMessageCallback::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
|
||||||
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
JS::Rooted<JSObject*> deleteArrayObj(cx,
|
JS::Rooted<JSObject*> deleteArrayObj(cx,
|
||||||
JS_NewArrayObject(cx, aSize, nullptr));
|
JS_NewArrayObject(cx, aSize));
|
||||||
for (uint32_t i = 0; i < aSize; i++) {
|
for (uint32_t i = 0; i < aSize; i++) {
|
||||||
JS_SetElement(cx, deleteArrayObj, i, aDeleted[i]);
|
JS_SetElement(cx, deleteArrayObj, i, aDeleted[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ MobileMessageManager::Send(JS::Handle<JS::Value> aNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> obj(aCx);
|
JS::Rooted<JSObject*> obj(aCx);
|
||||||
obj = JS_NewArrayObject(aCx, requests.length(), requests.begin());
|
obj = JS_NewArrayObject(aCx, requests);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ SmsFilter::GetNumbers(JSContext* aCx, JS::MutableHandle<JS::Value> aNumbers)
|
||||||
numbers[i].setString(str);
|
numbers[i].setString(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject* obj = JS_NewArrayObject(aCx, numbers.length(), numbers.begin());
|
JSObject* obj = JS_NewArrayObject(aCx, numbers);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,7 @@ GetParamsFromSendMmsMessageRequest(JSContext* aCx,
|
||||||
|
|
||||||
// attachments
|
// attachments
|
||||||
JS::Rooted<JSObject*> attachmentArray(aCx, JS_NewArrayObject(aCx,
|
JS::Rooted<JSObject*> attachmentArray(aCx, JS_NewArrayObject(aCx,
|
||||||
aRequest.attachments().Length(),
|
aRequest.attachments().Length()));
|
||||||
nullptr));
|
|
||||||
for (uint32_t i = 0; i < aRequest.attachments().Length(); i++) {
|
for (uint32_t i = 0; i < aRequest.attachments().Length(); i++) {
|
||||||
JS::Rooted<JSObject*> obj(aCx,
|
JS::Rooted<JSObject*> obj(aCx,
|
||||||
MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
|
MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
|
||||||
|
|
|
@ -608,7 +608,7 @@ public:
|
||||||
MOZ_ASSERT(aCountdown != 0);
|
MOZ_ASSERT(aCountdown != 0);
|
||||||
JSContext* cx = aGlobal.GetContext();
|
JSContext* cx = aGlobal.GetContext();
|
||||||
JSAutoCompartment ac(cx, aGlobal.Get());
|
JSAutoCompartment ac(cx, aGlobal.Get());
|
||||||
mValues = JS_NewArrayObject(cx, aCountdown, nullptr);
|
mValues = JS_NewArrayObject(cx, aCountdown);
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +731,7 @@ Promise::All(const GlobalObject& aGlobal, JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aIterable.Length() == 0) {
|
if (aIterable.Length() == 0) {
|
||||||
JS::Rooted<JSObject*> empty(aCx, JS_NewArrayObject(aCx, 0, nullptr));
|
JS::Rooted<JSObject*> empty(aCx, JS_NewArrayObject(aCx, 0));
|
||||||
if (!empty) {
|
if (!empty) {
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
MOZ_ASSERT(aPromise);
|
MOZ_ASSERT(aPromise);
|
||||||
JSContext* cx = aGlobal.GetContext();
|
JSContext* cx = aGlobal.GetContext();
|
||||||
JSAutoCompartment ac(cx, mGlobal);
|
JSAutoCompartment ac(cx, mGlobal);
|
||||||
mNotifications = JS_NewArrayObject(cx, 0, nullptr);
|
mNotifications = JS_NewArrayObject(cx, 0);
|
||||||
HoldData();
|
HoldData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ private:
|
||||||
JS::Rooted<JS::Value> stackValue(cx);
|
JS::Rooted<JS::Value> stackValue(cx);
|
||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> stackObj(cx,
|
JS::Rooted<JSObject*> stackObj(cx,
|
||||||
JS_NewArrayObject(cx, mStackData.Length(), nullptr));
|
JS_NewArrayObject(cx, mStackData.Length()));
|
||||||
if (!stackObj) {
|
if (!stackObj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -447,8 +447,7 @@ WorkerConsole::Method(JSContext* aCx, const char* aMethodName,
|
||||||
stack.swap(caller);
|
stack.swap(caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> arguments(aCx,
|
JS::Rooted<JSObject*> arguments(aCx, JS_NewArrayObject(aCx, aData.Length()));
|
||||||
JS_NewArrayObject(aCx, aData.Length(), nullptr));
|
|
||||||
if (!arguments) {
|
if (!arguments) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2707,9 +2707,15 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
if (aTransferable.WasPassed()) {
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
||||||
|
|
||||||
|
// The input sequence only comes from the generated bindings code, which
|
||||||
|
// ensures it is rooted.
|
||||||
|
JS::HandleValueArray elements =
|
||||||
|
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
||||||
|
realTransferable.Elements());
|
||||||
|
|
||||||
JSObject* array =
|
JSObject* array =
|
||||||
JS_NewArrayObject(aCx, realTransferable.Length(),
|
JS_NewArrayObject(aCx, elements);
|
||||||
const_cast<JS::Value*>(realTransferable.Elements()));
|
|
||||||
if (!array) {
|
if (!array) {
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
return;
|
return;
|
||||||
|
@ -4923,9 +4929,14 @@ WorkerPrivate::PostMessageToParentInternal(
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
if (aTransferable.WasPassed()) {
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
||||||
JSObject* array =
|
|
||||||
JS_NewArrayObject(aCx, realTransferable.Length(),
|
// The input sequence only comes from the generated bindings code, which
|
||||||
const_cast<jsval*>(realTransferable.Elements()));
|
// ensures it is rooted.
|
||||||
|
JS::HandleValueArray elements =
|
||||||
|
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
||||||
|
realTransferable.Elements());
|
||||||
|
|
||||||
|
JSObject* array = JS_NewArrayObject(aCx, elements);
|
||||||
if (!array) {
|
if (!array) {
|
||||||
aRv = NS_ERROR_OUT_OF_MEMORY;
|
aRv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "JoinElementTxn.h" // for JoinElementTxn
|
#include "JoinElementTxn.h" // for JoinElementTxn
|
||||||
#include "PlaceholderTxn.h" // for PlaceholderTxn
|
#include "PlaceholderTxn.h" // for PlaceholderTxn
|
||||||
#include "SplitElementTxn.h" // for SplitElementTxn
|
#include "SplitElementTxn.h" // for SplitElementTxn
|
||||||
|
#include "TextComposition.h" // for TextComposition
|
||||||
#include "mozFlushType.h" // for mozFlushType::Flush_Frames
|
#include "mozFlushType.h" // for mozFlushType::Flush_Frames
|
||||||
#include "mozISpellCheckingEngine.h"
|
#include "mozISpellCheckingEngine.h"
|
||||||
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
|
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
|
||||||
|
@ -139,12 +140,9 @@ nsEditor::nsEditor()
|
||||||
, mPlaceHolderBatch(0)
|
, mPlaceHolderBatch(0)
|
||||||
, mAction(EditAction::none)
|
, mAction(EditAction::none)
|
||||||
, mIMETextOffset(0)
|
, mIMETextOffset(0)
|
||||||
, mIMEBufferLength(0)
|
|
||||||
, mDirection(eNone)
|
, mDirection(eNone)
|
||||||
, mDocDirtyState(-1)
|
, mDocDirtyState(-1)
|
||||||
, mSpellcheckCheckboxState(eTriUnset)
|
, mSpellcheckCheckboxState(eTriUnset)
|
||||||
, mInIMEMode(false)
|
|
||||||
, mIsIMEComposing(false)
|
|
||||||
, mShouldTxnSetSelection(true)
|
, mShouldTxnSetSelection(true)
|
||||||
, mDidPreDestroy(false)
|
, mDidPreDestroy(false)
|
||||||
, mDidPostCreate(false)
|
, mDidPostCreate(false)
|
||||||
|
@ -248,8 +246,6 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIContent *aRoot, nsISelectionController *
|
||||||
/* initialize IME stuff */
|
/* initialize IME stuff */
|
||||||
mIMETextNode = nullptr;
|
mIMETextNode = nullptr;
|
||||||
mIMETextOffset = 0;
|
mIMETextOffset = 0;
|
||||||
mIMEBufferLength = 0;
|
|
||||||
|
|
||||||
/* Show the caret */
|
/* Show the caret */
|
||||||
selCon->SetCaretReadOnly(false);
|
selCon->SetCaretReadOnly(false);
|
||||||
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
||||||
|
@ -361,6 +357,10 @@ nsEditor::RemoveEventListeners()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reinterpret_cast<nsEditorEventListener*>(mEventListener.get())->Disconnect();
|
reinterpret_cast<nsEditorEventListener*>(mEventListener.get())->Disconnect();
|
||||||
|
if (mComposition) {
|
||||||
|
mComposition->EndHandlingComposition(this);
|
||||||
|
mComposition = nullptr;
|
||||||
|
}
|
||||||
mEventTarget = nullptr;
|
mEventTarget = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,7 +966,9 @@ nsEditor::EndPlaceHolderTransaction()
|
||||||
}
|
}
|
||||||
// notify editor observers of action but if composing, it's done by
|
// notify editor observers of action but if composing, it's done by
|
||||||
// text event handler.
|
// text event handler.
|
||||||
if (!mInIMEMode) NotifyEditorObservers();
|
if (!mComposition) {
|
||||||
|
NotifyEditorObservers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mPlaceHolderBatch--;
|
mPlaceHolderBatch--;
|
||||||
|
@ -2010,11 +2012,26 @@ nsEditor::StopPreservingSelection()
|
||||||
mSavedSel.MakeEmpty();
|
mSavedSel.MakeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsEditor::EnsureComposition(mozilla::WidgetGUIEvent* aEvent)
|
||||||
|
{
|
||||||
|
if (mComposition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// The compositionstart event must cause creating new TextComposition
|
||||||
|
// instance at being dispatched by nsIMEStateManager.
|
||||||
|
mComposition = nsIMEStateManager::GetTextCompositionFor(aEvent);
|
||||||
|
if (!mComposition) {
|
||||||
|
MOZ_CRASH("nsIMEStateManager doesn't return proper composition");
|
||||||
|
}
|
||||||
|
mComposition->StartHandlingComposition(this);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsEditor::BeginIMEComposition()
|
nsEditor::BeginIMEComposition(WidgetCompositionEvent* aCompositionEvent)
|
||||||
{
|
{
|
||||||
mInIMEMode = true;
|
MOZ_ASSERT(!mComposition, "There is composition already");
|
||||||
|
EnsureComposition(aCompositionEvent);
|
||||||
if (mPhonetic) {
|
if (mPhonetic) {
|
||||||
mPhonetic->Truncate(0);
|
mPhonetic->Truncate(0);
|
||||||
}
|
}
|
||||||
|
@ -2024,7 +2041,7 @@ nsEditor::BeginIMEComposition()
|
||||||
void
|
void
|
||||||
nsEditor::EndIMEComposition()
|
nsEditor::EndIMEComposition()
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE_VOID(mInIMEMode); // nothing to do
|
NS_ENSURE_TRUE_VOID(mComposition); // nothing to do
|
||||||
|
|
||||||
// commit the IME transaction..we can get at it via the transaction mgr.
|
// commit the IME transaction..we can get at it via the transaction mgr.
|
||||||
// Note that this means IME won't work without an undo stack!
|
// Note that this means IME won't work without an undo stack!
|
||||||
|
@ -2041,9 +2058,8 @@ nsEditor::EndIMEComposition()
|
||||||
/* reset the data we need to construct a transaction */
|
/* reset the data we need to construct a transaction */
|
||||||
mIMETextNode = nullptr;
|
mIMETextNode = nullptr;
|
||||||
mIMETextOffset = 0;
|
mIMETextOffset = 0;
|
||||||
mIMEBufferLength = 0;
|
mComposition->EndHandlingComposition(this);
|
||||||
mInIMEMode = false;
|
mComposition = nullptr;
|
||||||
mIsIMEComposing = false;
|
|
||||||
|
|
||||||
// notify editor observers of action
|
// notify editor observers of action
|
||||||
NotifyEditorObservers();
|
NotifyEditorObservers();
|
||||||
|
@ -2073,7 +2089,7 @@ nsEditor::ForceCompositionEnd()
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mInIMEMode) {
|
if (!mComposition) {
|
||||||
// XXXmnakano see bug 558976, ResetInputState() has two meaning which are
|
// XXXmnakano see bug 558976, ResetInputState() has two meaning which are
|
||||||
// "commit the composition" and "cursor is moved". This method name is
|
// "commit the composition" and "cursor is moved". This method name is
|
||||||
// "ForceCompositionEnd", so, ResetInputState() should be used only for the
|
// "ForceCompositionEnd", so, ResetInputState() should be used only for the
|
||||||
|
@ -2312,7 +2328,7 @@ nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||||
|
|
||||||
NS_ENSURE_TRUE(aInOutNode && *aInOutNode && aInOutOffset && aDoc,
|
NS_ENSURE_TRUE(aInOutNode && *aInOutNode && aInOutOffset && aDoc,
|
||||||
NS_ERROR_NULL_POINTER);
|
NS_ERROR_NULL_POINTER);
|
||||||
if (!mInIMEMode && aStringToInsert.IsEmpty()) {
|
if (!mComposition && aStringToInsert.IsEmpty()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2352,7 +2368,7 @@ nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult res;
|
nsresult res;
|
||||||
if (mInIMEMode) {
|
if (mComposition) {
|
||||||
if (!node->IsNodeOfType(nsINode::eTEXT)) {
|
if (!node->IsNodeOfType(nsINode::eTEXT)) {
|
||||||
// create a text node
|
// create a text node
|
||||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||||
|
@ -2407,7 +2423,7 @@ nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||||
bool isIMETransaction = false;
|
bool isIMETransaction = false;
|
||||||
// aSuppressIME is used when editor must insert text, yet this text is not
|
// aSuppressIME is used when editor must insert text, yet this text is not
|
||||||
// part of current ime operation. example: adjusting whitespace around an ime insertion.
|
// part of current ime operation. example: adjusting whitespace around an ime insertion.
|
||||||
if (mIMETextRangeList && mInIMEMode && !aSuppressIME)
|
if (mIMETextRangeList && mComposition && !aSuppressIME)
|
||||||
{
|
{
|
||||||
if (!mIMETextNode)
|
if (!mIMETextNode)
|
||||||
{
|
{
|
||||||
|
@ -4179,45 +4195,16 @@ nsEditor::DeleteSelectionAndCreateNode(const nsAString& aTag,
|
||||||
|
|
||||||
/* Non-interface, protected methods */
|
/* Non-interface, protected methods */
|
||||||
|
|
||||||
int32_t
|
TextComposition*
|
||||||
nsEditor::GetIMEBufferLength()
|
nsEditor::GetComposition() const
|
||||||
{
|
{
|
||||||
return mIMEBufferLength;
|
return mComposition;
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsEditor::SetIsIMEComposing(){
|
|
||||||
// We set mIsIMEComposing according to mIMETextRangeList.
|
|
||||||
nsCOMPtr<nsIPrivateTextRange> rangePtr;
|
|
||||||
uint16_t listlen, type;
|
|
||||||
|
|
||||||
mIsIMEComposing = false;
|
|
||||||
listlen = mIMETextRangeList->GetLength();
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < listlen; i++)
|
|
||||||
{
|
|
||||||
rangePtr = mIMETextRangeList->Item(i);
|
|
||||||
if (!rangePtr) continue;
|
|
||||||
nsresult result = rangePtr->GetRangeType(&type);
|
|
||||||
if (NS_FAILED(result)) continue;
|
|
||||||
if ( type == nsIPrivateTextRange::TEXTRANGE_RAWINPUT ||
|
|
||||||
type == nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT ||
|
|
||||||
type == nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT ||
|
|
||||||
type == nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT )
|
|
||||||
{
|
|
||||||
mIsIMEComposing = true;
|
|
||||||
#ifdef DEBUG_IME
|
|
||||||
printf("nsEditor::mIsIMEComposing = true\n");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsEditor::IsIMEComposing() {
|
nsEditor::IsIMEComposing() const
|
||||||
return mIsIMEComposing;
|
{
|
||||||
|
return mComposition && mComposition->IsComposing();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -4414,7 +4401,9 @@ nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert,
|
||||||
|
|
||||||
nsRefPtr<IMETextTxn> txn = new IMETextTxn();
|
nsRefPtr<IMETextTxn> txn = new IMETextTxn();
|
||||||
|
|
||||||
nsresult rv = txn->Init(mIMETextNode, mIMETextOffset, mIMEBufferLength,
|
// During handling IME composition, mComposition must have been initialized.
|
||||||
|
nsresult rv = txn->Init(mIMETextNode, mIMETextOffset,
|
||||||
|
mComposition->String().Length(),
|
||||||
mIMETextRangeList, aStringToInsert, this);
|
mIMETextRangeList, aStringToInsert, this);
|
||||||
if (NS_SUCCEEDED(rv))
|
if (NS_SUCCEEDED(rv))
|
||||||
{
|
{
|
||||||
|
@ -5225,6 +5214,23 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
|
||||||
if (!focusedContent) {
|
if (!focusedContent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nsAutoString eventType;
|
||||||
|
aEvent->GetType(eventType);
|
||||||
|
// If composition event or text event isn't dispatched via widget,
|
||||||
|
// we need to ignore them since they cannot be managed by TextComposition.
|
||||||
|
// E.g., the event was created by chrome JS.
|
||||||
|
// Note that if we allow to handle such events, editor may be confused by
|
||||||
|
// strange event order.
|
||||||
|
if (eventType.EqualsLiteral("text") ||
|
||||||
|
eventType.EqualsLiteral("compositionstart") ||
|
||||||
|
eventType.EqualsLiteral("compositionend")) {
|
||||||
|
WidgetGUIEvent* widgetGUIEvent =
|
||||||
|
aEvent->GetInternalNSEvent()->AsGUIEvent();
|
||||||
|
if (!widgetGUIEvent || !widgetGUIEvent->widget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTrusted;
|
bool isTrusted;
|
||||||
|
|
|
@ -69,6 +69,7 @@ class nsTransactionManager;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class Selection;
|
class Selection;
|
||||||
|
class TextComposition;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class Element;
|
class Element;
|
||||||
|
@ -242,9 +243,8 @@ public:
|
||||||
mozilla::dom::Element** aContent);
|
mozilla::dom::Element** aContent);
|
||||||
|
|
||||||
// IME event handlers
|
// IME event handlers
|
||||||
virtual nsresult BeginIMEComposition();
|
virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
|
||||||
virtual nsresult UpdateIMEComposition(const nsAString &aCompositionString,
|
virtual nsresult UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) = 0;
|
||||||
nsIPrivateTextRangeList *aTextRange)=0;
|
|
||||||
void EndIMEComposition();
|
void EndIMEComposition();
|
||||||
|
|
||||||
void SwitchTextDirectionTo(uint32_t aDirection);
|
void SwitchTextDirectionTo(uint32_t aDirection);
|
||||||
|
@ -413,6 +413,13 @@ protected:
|
||||||
return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
|
return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EnsureComposition() should be composition event handlers or text event
|
||||||
|
* handler. This tries to get the composition for the event and set it to
|
||||||
|
* mComposition.
|
||||||
|
*/
|
||||||
|
void EnsureComposition(mozilla::WidgetGUIEvent* aEvent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** All editor operations which alter the doc should be prefaced
|
/** All editor operations which alter the doc should be prefaced
|
||||||
|
@ -592,9 +599,14 @@ public:
|
||||||
/** Find the deep first and last children. */
|
/** Find the deep first and last children. */
|
||||||
nsINode* GetFirstEditableNode(nsINode* aRoot);
|
nsINode* GetFirstEditableNode(nsINode* aRoot);
|
||||||
|
|
||||||
int32_t GetIMEBufferLength();
|
/**
|
||||||
bool IsIMEComposing(); /* test if IME is in composition state */
|
* Returns current composition.
|
||||||
void SetIsIMEComposing(); /* call this before |IsIMEComposing()| */
|
*/
|
||||||
|
mozilla::TextComposition* GetComposition() const;
|
||||||
|
/**
|
||||||
|
* Returns true if there is composition string and not fixed.
|
||||||
|
*/
|
||||||
|
bool IsIMEComposing() const;
|
||||||
|
|
||||||
/** from html rules code - migration in progress */
|
/** from html rules code - migration in progress */
|
||||||
static nsresult GetTagString(nsIDOMNode *aNode, nsAString& outString);
|
static nsresult GetTagString(nsIDOMNode *aNode, nsAString& outString);
|
||||||
|
@ -830,6 +842,9 @@ protected:
|
||||||
nsIAtom *mPlaceHolderName; // name of placeholder transaction
|
nsIAtom *mPlaceHolderName; // name of placeholder transaction
|
||||||
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
|
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
|
||||||
nsString *mPhonetic;
|
nsString *mPhonetic;
|
||||||
|
// IME composition this is not null between compositionstart and
|
||||||
|
// compositionend.
|
||||||
|
nsRefPtr<mozilla::TextComposition> mComposition;
|
||||||
|
|
||||||
// various listeners
|
// various listeners
|
||||||
nsCOMArray<nsIEditActionListener> mActionListeners; // listens to all low level actions on the doc
|
nsCOMArray<nsIEditActionListener> mActionListeners; // listens to all low level actions on the doc
|
||||||
|
@ -848,16 +863,11 @@ protected:
|
||||||
EditAction mAction; // the current editor action
|
EditAction mAction; // the current editor action
|
||||||
|
|
||||||
uint32_t mIMETextOffset; // offset in text node where IME comp string begins
|
uint32_t mIMETextOffset; // offset in text node where IME comp string begins
|
||||||
uint32_t mIMEBufferLength; // current length of IME comp string
|
|
||||||
|
|
||||||
EDirection mDirection; // the current direction of editor action
|
EDirection mDirection; // the current direction of editor action
|
||||||
int8_t mDocDirtyState; // -1 = not initialized
|
int8_t mDocDirtyState; // -1 = not initialized
|
||||||
uint8_t mSpellcheckCheckboxState; // a Tristate value
|
uint8_t mSpellcheckCheckboxState; // a Tristate value
|
||||||
|
|
||||||
bool mInIMEMode; // are we inside an IME composition?
|
|
||||||
bool mIsIMEComposing; // is IME in composition state?
|
|
||||||
// This is different from mInIMEMode. see Bug 98434.
|
|
||||||
|
|
||||||
bool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
|
bool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
|
||||||
bool mDidPreDestroy; // whether PreDestroy has been called
|
bool mDidPreDestroy; // whether PreDestroy has been called
|
||||||
bool mDidPostCreate; // whether PostCreate has been called
|
bool mDidPostCreate; // whether PostCreate has been called
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||||
#include "mozilla/Preferences.h" // for Preferences
|
#include "mozilla/Preferences.h" // for Preferences
|
||||||
|
#include "mozilla/TextEvents.h" // for WidgetCompositionEvent
|
||||||
#include "mozilla/dom/Element.h" // for Element
|
#include "mozilla/dom/Element.h" // for Element
|
||||||
#include "mozilla/dom/EventTarget.h" // for EventTarget
|
#include "mozilla/dom/EventTarget.h" // for EventTarget
|
||||||
#include "nsAString.h"
|
#include "nsAString.h"
|
||||||
|
@ -42,8 +43,6 @@
|
||||||
#include "nsINode.h" // for nsINode, ::NODE_IS_EDITABLE, etc
|
#include "nsINode.h" // for nsINode, ::NODE_IS_EDITABLE, etc
|
||||||
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
|
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
|
||||||
#include "nsIPresShell.h" // for nsIPresShell
|
#include "nsIPresShell.h" // for nsIPresShell
|
||||||
#include "nsIPrivateTextEvent.h" // for nsIPrivateTextEvent
|
|
||||||
#include "nsIPrivateTextRange.h" // for nsIPrivateTextRangeList
|
|
||||||
#include "nsISelection.h" // for nsISelection
|
#include "nsISelection.h" // for nsISelection
|
||||||
#include "nsISelectionController.h" // for nsISelectionController, etc
|
#include "nsISelectionController.h" // for nsISelectionController, etc
|
||||||
#include "nsISelectionPrivate.h" // for nsISelectionPrivate
|
#include "nsISelectionPrivate.h" // for nsISelectionPrivate
|
||||||
|
@ -661,24 +660,12 @@ nsEditorEventListener::HandleText(nsIDOMEvent* aTextEvent)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPrivateTextEvent> textEvent = do_QueryInterface(aTextEvent);
|
|
||||||
if (!textEvent) {
|
|
||||||
//non-ui event passed in. bad things.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString composedText;
|
|
||||||
nsCOMPtr<nsIPrivateTextRangeList> textRangeList;
|
|
||||||
|
|
||||||
textEvent->GetText(composedText);
|
|
||||||
textRangeList = textEvent->GetInputRange();
|
|
||||||
|
|
||||||
// if we are readonly or disabled, then do nothing.
|
// if we are readonly or disabled, then do nothing.
|
||||||
if (mEditor->IsReadonly() || mEditor->IsDisabled()) {
|
if (mEditor->IsReadonly() || mEditor->IsDisabled()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mEditor->UpdateIMEComposition(composedText, textRangeList);
|
return mEditor->UpdateIMEComposition(aTextEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -905,7 +892,9 @@ nsEditorEventListener::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
|
||||||
if (!mEditor->IsAcceptableInputEvent(aCompositionEvent)) {
|
if (!mEditor->IsAcceptableInputEvent(aCompositionEvent)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
return mEditor->BeginIMEComposition();
|
WidgetCompositionEvent* compositionStart =
|
||||||
|
aCompositionEvent->GetInternalNSEvent()->AsCompositionEvent();
|
||||||
|
return mEditor->BeginIMEComposition(compositionStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -20,6 +20,7 @@ FAIL_ON_WARNINGS = True
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'../base',
|
'../base',
|
||||||
'/content/base/src',
|
'/content/base/src',
|
||||||
|
'/dom/events',
|
||||||
'/editor/txmgr/src',
|
'/editor/txmgr/src',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
|
||||||
|
#include "TextComposition.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Selection.h"
|
#include "mozilla/Selection.h"
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
#include "nsINameSpaceManager.h"
|
#include "nsINameSpaceManager.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsIPrivateTextEvent.h"
|
||||||
#include "nsIPrivateTextRange.h"
|
#include "nsIPrivateTextRange.h"
|
||||||
#include "nsISelection.h"
|
#include "nsISelection.h"
|
||||||
#include "nsISelectionController.h"
|
#include "nsISelectionController.h"
|
||||||
|
@ -695,8 +697,7 @@ NS_IMETHODIMP nsPlaintextEditor::InsertText(const nsAString &aStringToInsert)
|
||||||
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
||||||
|
|
||||||
EditAction opID = EditAction::insertText;
|
EditAction opID = EditAction::insertText;
|
||||||
if (mInIMEMode)
|
if (mComposition) {
|
||||||
{
|
|
||||||
opID = EditAction::insertIMEText;
|
opID = EditAction::insertIMEText;
|
||||||
}
|
}
|
||||||
nsAutoPlaceHolderBatch batch(this, nullptr);
|
nsAutoPlaceHolderBatch batch(this, nullptr);
|
||||||
|
@ -811,9 +812,9 @@ NS_IMETHODIMP nsPlaintextEditor::InsertLineBreak()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsPlaintextEditor::BeginIMEComposition()
|
nsPlaintextEditor::BeginIMEComposition(WidgetCompositionEvent* aEvent)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(!mInIMEMode, NS_OK);
|
NS_ENSURE_TRUE(!mComposition, NS_OK);
|
||||||
|
|
||||||
if (IsPasswordEditor()) {
|
if (IsPasswordEditor()) {
|
||||||
NS_ENSURE_TRUE(mRules, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(mRules, NS_ERROR_NULL_POINTER);
|
||||||
|
@ -825,14 +826,19 @@ nsPlaintextEditor::BeginIMEComposition()
|
||||||
textEditRules->ResetIMETextPWBuf();
|
textEditRules->ResetIMETextPWBuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsEditor::BeginIMEComposition();
|
return nsEditor::BeginIMEComposition(aEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
|
nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent)
|
||||||
nsIPrivateTextRangeList* aTextRangeList)
|
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aTextRangeList, "aTextRangeList must not be nullptr");
|
NS_ABORT_IF_FALSE(aDOMTextEvent, "aDOMTextEvent must not be nullptr");
|
||||||
|
|
||||||
|
WidgetTextEvent* widgetTextEvent =
|
||||||
|
aDOMTextEvent->GetInternalNSEvent()->AsTextEvent();
|
||||||
|
NS_ENSURE_TRUE(widgetTextEvent, NS_ERROR_INVALID_ARG);
|
||||||
|
|
||||||
|
EnsureComposition(widgetTextEvent);
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
nsCOMPtr<nsIPresShell> ps = GetPresShell();
|
||||||
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
|
||||||
|
@ -843,19 +849,23 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
|
||||||
|
|
||||||
nsRefPtr<nsCaret> caretP = ps->GetCaret();
|
nsRefPtr<nsCaret> caretP = ps->GetCaret();
|
||||||
|
|
||||||
// Update information of clauses in the new composition string.
|
nsCOMPtr<nsIPrivateTextEvent> privateTextEvent =
|
||||||
// This will be refered by followed methods.
|
do_QueryInterface(aDOMTextEvent);
|
||||||
mIMETextRangeList = aTextRangeList;
|
NS_ENSURE_TRUE(privateTextEvent, NS_ERROR_INVALID_ARG);
|
||||||
|
|
||||||
// We set mIsIMEComposing properly.
|
|
||||||
SetIsIMEComposing();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
TextComposition::TextEventHandlingMarker
|
||||||
|
textEventHandlingMarker(mComposition, widgetTextEvent);
|
||||||
|
|
||||||
|
// Update information of clauses in the new composition string.
|
||||||
|
// This will be refered by followed methods.
|
||||||
|
mIMETextRangeList = privateTextEvent->GetInputRange();
|
||||||
|
NS_ABORT_IF_FALSE(mIMETextRangeList,
|
||||||
|
"mIMETextRangeList must not be nullptr");
|
||||||
|
|
||||||
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
|
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
|
||||||
|
|
||||||
rv = InsertText(aCompositionString);
|
rv = InsertText(widgetTextEvent->theText);
|
||||||
|
|
||||||
mIMEBufferLength = aCompositionString.Length();
|
|
||||||
|
|
||||||
if (caretP) {
|
if (caretP) {
|
||||||
caretP->SetCaretDOMSelection(selection);
|
caretP->SetCaretDOMSelection(selection);
|
||||||
|
@ -866,7 +876,7 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
|
||||||
// Note that if committed, we don't need to notify it since it will be
|
// Note that if committed, we don't need to notify it since it will be
|
||||||
// notified at followed compositionend event.
|
// notified at followed compositionend event.
|
||||||
// NOTE: We must notify after the auto batch will be gone.
|
// NOTE: We must notify after the auto batch will be gone.
|
||||||
if (mIsIMEComposing) {
|
if (IsIMEComposing()) {
|
||||||
NotifyEditorObservers();
|
NotifyEditorObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,9 +122,8 @@ public:
|
||||||
|
|
||||||
virtual already_AddRefed<mozilla::dom::EventTarget> GetDOMEventTarget();
|
virtual already_AddRefed<mozilla::dom::EventTarget> GetDOMEventTarget();
|
||||||
|
|
||||||
virtual nsresult BeginIMEComposition();
|
virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
|
||||||
virtual nsresult UpdateIMEComposition(const nsAString &aCompositionString,
|
virtual nsresult UpdateIMEComposition(nsIDOMEvent* aTextEvent) MOZ_OVERRIDE;
|
||||||
nsIPrivateTextRangeList *aTextRange);
|
|
||||||
|
|
||||||
virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
|
virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "TextComposition.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
@ -1208,7 +1209,8 @@ nsTextEditRules::TruncateInsertionIfNeeded(Selection* aSelection,
|
||||||
nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(),
|
nsContentUtils::GetSelectionInTextControl(aSelection, mEditor->GetRoot(),
|
||||||
start, end);
|
start, end);
|
||||||
|
|
||||||
int32_t oldCompStrLength = mEditor->GetIMEBufferLength();
|
TextComposition* composition = mEditor->GetComposition();
|
||||||
|
int32_t oldCompStrLength = composition ? composition->String().Length() : 0;
|
||||||
|
|
||||||
const int32_t selectionLength = end - start;
|
const int32_t selectionLength = end - start;
|
||||||
const int32_t resultingDocLength = docLength - selectionLength - oldCompStrLength;
|
const int32_t resultingDocLength = docLength - selectionLength - oldCompStrLength;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include <initguid.h>
|
||||||
#include "DrawTargetD2D1.h"
|
#include "DrawTargetD2D1.h"
|
||||||
#include "DrawTargetD2D.h"
|
#include "DrawTargetD2D.h"
|
||||||
#include "FilterNodeSoftware.h"
|
#include "FilterNodeSoftware.h"
|
||||||
|
|
|
@ -50,11 +50,11 @@ static const PCWSTR kXmlDescription =
|
||||||
);
|
);
|
||||||
|
|
||||||
// {FB947CDA-718E-40CC-AE7B-D255830D7D14}
|
// {FB947CDA-718E-40CC-AE7B-D255830D7D14}
|
||||||
DEFINE_GUID(GUID_SampleRadialGradientPS,
|
static const GUID GUID_SampleRadialGradientPS =
|
||||||
0xfb947cda, 0x718e, 0x40cc, 0xae, 0x7b, 0xd2, 0x55, 0x83, 0xd, 0x7d, 0x14);
|
{0xfb947cda, 0x718e, 0x40cc, {0xae, 0x7b, 0xd2, 0x55, 0x83, 0xd, 0x7d, 0x14}};
|
||||||
// {2C468128-6546-453C-8E25-F2DF0DE10A0F}
|
// {2C468128-6546-453C-8E25-F2DF0DE10A0F}
|
||||||
DEFINE_GUID(GUID_SampleRadialGradientA0PS,
|
static const GUID GUID_SampleRadialGradientA0PS =
|
||||||
0x2c468128, 0x6546, 0x453c, 0x8e, 0x25, 0xf2, 0xdf, 0xd, 0xe1, 0xa, 0xf);
|
{0x2c468128, 0x6546, 0x453c, {0x8e, 0x25, 0xf2, 0xdf, 0xd, 0xe1, 0xa, 0xf}};
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>INITGUID;USE_SSE2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
|
<PreprocessorDefinitions>USE_SSE2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>INITGUID;USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
|
|
@ -52,7 +52,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
'SourceSurfaceD2DTarget.cpp',
|
'SourceSurfaceD2DTarget.cpp',
|
||||||
]
|
]
|
||||||
DEFINES['WIN32'] = True
|
DEFINES['WIN32'] = True
|
||||||
DEFINES['INITGUID'] = True
|
|
||||||
# For Direct2D 1.1 we require WINSDK_MAXVER 0x06020000 or higher.
|
# For Direct2D 1.1 we require WINSDK_MAXVER 0x06020000 or higher.
|
||||||
if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
|
if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
|
|
|
@ -76,6 +76,7 @@ static const char *sExtensionNames[] = {
|
||||||
"GL_IMG_read_format",
|
"GL_IMG_read_format",
|
||||||
"GL_EXT_read_format_bgra",
|
"GL_EXT_read_format_bgra",
|
||||||
"GL_APPLE_client_storage",
|
"GL_APPLE_client_storage",
|
||||||
|
"GL_APPLE_texture_range",
|
||||||
"GL_ARB_texture_non_power_of_two",
|
"GL_ARB_texture_non_power_of_two",
|
||||||
"GL_ARB_pixel_buffer_object",
|
"GL_ARB_pixel_buffer_object",
|
||||||
"GL_ARB_ES2_compatibility",
|
"GL_ARB_ES2_compatibility",
|
||||||
|
@ -756,6 +757,17 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsExtensionSupported(APPLE_texture_range)) {
|
||||||
|
SymLoadStruct vaoSymbols[] = {
|
||||||
|
{ (PRFuncPtr*) &mSymbols.fTextureRangeAPPLE, { "TextureRangeAPPLE", nullptr } },
|
||||||
|
{ nullptr, { nullptr } },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
|
||||||
|
mSymbols.fTextureRangeAPPLE = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsExtensionSupported(ARB_vertex_array_object) ||
|
if (IsExtensionSupported(ARB_vertex_array_object) ||
|
||||||
IsExtensionSupported(OES_vertex_array_object)) {
|
IsExtensionSupported(OES_vertex_array_object)) {
|
||||||
SymLoadStruct vaoSymbols[] = {
|
SymLoadStruct vaoSymbols[] = {
|
||||||
|
|
|
@ -352,6 +352,7 @@ public:
|
||||||
IMG_read_format,
|
IMG_read_format,
|
||||||
EXT_read_format_bgra,
|
EXT_read_format_bgra,
|
||||||
APPLE_client_storage,
|
APPLE_client_storage,
|
||||||
|
APPLE_texture_range,
|
||||||
ARB_texture_non_power_of_two,
|
ARB_texture_non_power_of_two,
|
||||||
ARB_pixel_buffer_object,
|
ARB_pixel_buffer_object,
|
||||||
ARB_ES2_compatibility,
|
ARB_ES2_compatibility,
|
||||||
|
@ -1344,6 +1345,12 @@ public:
|
||||||
AFTER_GL_CALL;
|
AFTER_GL_CALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid *pointer) {
|
||||||
|
BEFORE_GL_CALL;
|
||||||
|
mSymbols.fTextureRangeAPPLE(target, length, pointer);
|
||||||
|
AFTER_GL_CALL;
|
||||||
|
}
|
||||||
|
|
||||||
void fPointParameterf(GLenum pname, GLfloat param) {
|
void fPointParameterf(GLenum pname, GLfloat param) {
|
||||||
BEFORE_GL_CALL;
|
BEFORE_GL_CALL;
|
||||||
mSymbols.fPointParameterf(pname, param);
|
mSymbols.fPointParameterf(pname, param);
|
||||||
|
|
|
@ -211,6 +211,8 @@ struct GLContextSymbols
|
||||||
PFNGLTEXIMAGE2DPROC fTexImage2D;
|
PFNGLTEXIMAGE2DPROC fTexImage2D;
|
||||||
typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
|
typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
|
||||||
PFNGLTEXSUBIMAGE2DPROC fTexSubImage2D;
|
PFNGLTEXSUBIMAGE2DPROC fTexSubImage2D;
|
||||||
|
typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer);
|
||||||
|
PFNGLTEXTURERANGEAPPLEPROC fTextureRangeAPPLE;
|
||||||
typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
|
typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
|
||||||
PFNGLUNIFORM1FPROC fUniform1f;
|
PFNGLUNIFORM1FPROC fUniform1f;
|
||||||
typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
|
typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "SharedSurfaceIO.h"
|
#include "SharedSurfaceIO.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ScopedGLHelpers.h"
|
#include "ScopedGLHelpers.h"
|
||||||
|
#include "gfx2DGlue.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
|
@ -478,9 +479,22 @@ GLScreenBuffer::CreateRead(SharedSurface_GL* surf)
|
||||||
return ReadBuffer::Create(gl, caps, formats, surf);
|
return ReadBuffer::Create(gl, caps, formats, surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GLScreenBuffer::Readback(SharedSurface_GL* src, DataSourceSurface* dest)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(src && dest);
|
||||||
|
DataSourceSurface::MappedSurface ms;
|
||||||
|
dest->Map(DataSourceSurface::MapType::READ, &ms);
|
||||||
|
nsRefPtr<gfxImageSurface> wrappedDest =
|
||||||
|
new gfxImageSurface(ms.mData,
|
||||||
|
ThebesIntSize(dest->GetSize()),
|
||||||
|
ms.mStride,
|
||||||
|
SurfaceFormatToImageFormat(dest->GetFormat()));
|
||||||
|
DeprecatedReadback(src, wrappedDest);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GLScreenBuffer::Readback(SharedSurface_GL* src, gfxImageSurface* dest)
|
GLScreenBuffer::DeprecatedReadback(SharedSurface_GL* src, gfxImageSurface* dest)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(src && dest);
|
MOZ_ASSERT(src && dest);
|
||||||
MOZ_ASSERT(ToIntSize(dest->GetSize()) == src->Size());
|
MOZ_ASSERT(ToIntSize(dest->GetSize()) == src->Size());
|
||||||
|
@ -509,8 +523,6 @@ GLScreenBuffer::Readback(SharedSurface_GL* src, gfxImageSurface* dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DrawBuffer*
|
DrawBuffer*
|
||||||
DrawBuffer::Create(GLContext* const gl,
|
DrawBuffer::Create(GLContext* const gl,
|
||||||
const SurfaceCaps& caps,
|
const SurfaceCaps& caps,
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "SurfaceTypes.h"
|
#include "SurfaceTypes.h"
|
||||||
#include "GLContextTypes.h"
|
#include "GLContextTypes.h"
|
||||||
#include "GLDefs.h"
|
#include "GLDefs.h"
|
||||||
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/gfx/Point.h"
|
#include "mozilla/gfx/Point.h"
|
||||||
|
|
||||||
// Forwards:
|
// Forwards:
|
||||||
|
@ -277,7 +278,8 @@ public:
|
||||||
|
|
||||||
bool Resize(const gfx::IntSize& size);
|
bool Resize(const gfx::IntSize& size);
|
||||||
|
|
||||||
void Readback(SharedSurface_GL* src, gfxImageSurface* dest);
|
void Readback(SharedSurface_GL* src, gfx::DataSourceSurface* dest);
|
||||||
|
void DeprecatedReadback(SharedSurface_GL* src, gfxImageSurface* dest);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Attach(SharedSurface* surface, const gfx::IntSize& size);
|
void Attach(SharedSurface* surface, const gfx::IntSize& size);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
|
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
|
||||||
#include "nsRect.h" // for nsIntRect
|
#include "nsRect.h" // for nsIntRect
|
||||||
#include "nsSize.h" // for nsIntSize
|
#include "nsSize.h" // for nsIntSize
|
||||||
|
#include "LayerUtils.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
using namespace mozilla::gl;
|
using namespace mozilla::gl;
|
||||||
|
@ -56,7 +57,8 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
||||||
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
|
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
|
||||||
} else if (aData.mDrawTarget) {
|
} else if (aData.mDrawTarget) {
|
||||||
mDrawTarget = aData.mDrawTarget;
|
mDrawTarget = aData.mDrawTarget;
|
||||||
mSurface =
|
mSurface = mDrawTarget->Snapshot();
|
||||||
|
mDeprecatedSurface =
|
||||||
gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
||||||
mNeedsYFlip = false;
|
mNeedsYFlip = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,7 +75,8 @@ CopyableCanvasLayer::IsDataValid(const Data& aData)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget,
|
||||||
|
SourceSurface* aMaskSurface)
|
||||||
{
|
{
|
||||||
if (!IsDirty())
|
if (!IsDirty())
|
||||||
return;
|
return;
|
||||||
|
@ -81,14 +84,105 @@ CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||||
|
|
||||||
if (mDrawTarget) {
|
if (mDrawTarget) {
|
||||||
mDrawTarget->Flush();
|
mDrawTarget->Flush();
|
||||||
mSurface =
|
mSurface = mDrawTarget->Snapshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mGLContext && aDestTarget) {
|
||||||
|
PaintWithOpacity(aDestTarget, 1.0f, aMaskSurface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGLContext) {
|
||||||
|
RefPtr<DataSourceSurface> readSurf;
|
||||||
|
RefPtr<SourceSurface> resultSurf;
|
||||||
|
|
||||||
|
SharedSurface* sharedSurf = mGLContext->RequestFrame();
|
||||||
|
if (!sharedSurf) {
|
||||||
|
NS_WARNING("Null frame received.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntSize readSize(sharedSurf->Size());
|
||||||
|
SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||||
|
? SurfaceFormat::B8G8R8X8
|
||||||
|
: SurfaceFormat::B8G8R8A8;
|
||||||
|
|
||||||
|
if (aDestTarget) {
|
||||||
|
resultSurf = aDestTarget->Snapshot();
|
||||||
|
if (!resultSurf) {
|
||||||
|
resultSurf = GetTempSurface(readSize, format);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultSurf = GetTempSurface(readSize, format);
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(resultSurf);
|
||||||
|
MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL);
|
||||||
|
SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf);
|
||||||
|
|
||||||
|
if (surfGL->Type() == SharedSurfaceType::Basic) {
|
||||||
|
// sharedSurf_Basic->mData must outlive readSurf. Alas, readSurf may not
|
||||||
|
// leave the scope it was declared in.
|
||||||
|
SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL);
|
||||||
|
readSurf = sharedSurf_Basic->GetData();
|
||||||
|
} else {
|
||||||
|
if (resultSurf->GetSize() != readSize ||
|
||||||
|
!(readSurf = resultSurf->GetDataSurface()) ||
|
||||||
|
readSurf->GetFormat() != format)
|
||||||
|
{
|
||||||
|
readSurf = GetTempSurface(readSize, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Readback handles Flush/MarkDirty.
|
||||||
|
mGLContext->Screen()->Readback(surfGL, readSurf);
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(readSurf);
|
||||||
|
|
||||||
|
bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult;
|
||||||
|
if (needsPremult) {
|
||||||
|
PremultiplySurface(readSurf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readSurf != resultSurf) {
|
||||||
|
RefPtr<DataSourceSurface> resultDataSurface =
|
||||||
|
resultSurf->GetDataSurface();
|
||||||
|
RefPtr<DrawTarget> dt =
|
||||||
|
Factory::CreateDrawTargetForData(BackendType::CAIRO,
|
||||||
|
resultDataSurface->GetData(),
|
||||||
|
resultDataSurface->GetSize(),
|
||||||
|
resultDataSurface->Stride(),
|
||||||
|
resultDataSurface->GetFormat());
|
||||||
|
IntSize readSize = readSurf->GetSize();
|
||||||
|
Rect r(0, 0, readSize.width, readSize.height);
|
||||||
|
DrawOptions opts(1.0f, CompositionOp::OP_SOURCE, AntialiasMode::DEFAULT);
|
||||||
|
dt->DrawSurface(readSurf, r, r, DrawSurfaceOptions(), opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If !aDestSurface then we will end up painting using mSurface, so
|
||||||
|
// stick our surface into mSurface, so that the Paint() path is the same.
|
||||||
|
if (!aDestTarget) {
|
||||||
|
mSurface = resultSurf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CopyableCanvasLayer::DeprecatedUpdateSurface(gfxASurface* aDestSurface,
|
||||||
|
Layer* aMaskLayer)
|
||||||
|
{
|
||||||
|
if (!IsDirty())
|
||||||
|
return;
|
||||||
|
Painted();
|
||||||
|
|
||||||
|
if (mDrawTarget) {
|
||||||
|
mDrawTarget->Flush();
|
||||||
|
mDeprecatedSurface =
|
||||||
gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mGLContext && aDestSurface) {
|
if (!mGLContext && aDestSurface) {
|
||||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
|
nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
|
||||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer);
|
DeprecatedPaintWithOpacity(tmpCtx, 1.0f, aMaskLayer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +205,7 @@ CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||||
if (aDestSurface) {
|
if (aDestSurface) {
|
||||||
resultSurf = aDestSurface;
|
resultSurf = aDestSurface;
|
||||||
} else {
|
} else {
|
||||||
resultSurf = GetTempSurface(readSize, format);
|
resultSurf = DeprecatedGetTempSurface(readSize, format);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(resultSurf);
|
MOZ_ASSERT(resultSurf);
|
||||||
if (resultSurf->CairoStatus() != 0) {
|
if (resultSurf->CairoStatus() != 0) {
|
||||||
|
@ -136,11 +230,11 @@ CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||||
!(readSurf = resultSurf->GetAsImageSurface()) ||
|
!(readSurf = resultSurf->GetAsImageSurface()) ||
|
||||||
readSurf->Format() != format)
|
readSurf->Format() != format)
|
||||||
{
|
{
|
||||||
readSurf = GetTempSurface(readSize, format);
|
readSurf = DeprecatedGetTempSurface(readSize, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Readback handles Flush/MarkDirty.
|
// Readback handles Flush/MarkDirty.
|
||||||
mGLContext->Screen()->Readback(surfGL, readSurf);
|
mGLContext->Screen()->DeprecatedReadback(surfGL, readSurf);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(readSurf);
|
MOZ_ASSERT(readSurf);
|
||||||
|
|
||||||
|
@ -150,7 +244,7 @@ CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||||
gfxUtils::PremultiplyImageSurface(readSurf);
|
gfxUtils::PremultiplyImageSurface(readSurf);
|
||||||
readSurf->MarkDirty();
|
readSurf->MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readSurf != resultSurf) {
|
if (readSurf != resultSurf) {
|
||||||
readSurf->Flush();
|
readSurf->Flush();
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
||||||
|
@ -162,23 +256,69 @@ CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||||
// If !aDestSurface then we will end up painting using mSurface, so
|
// If !aDestSurface then we will end up painting using mSurface, so
|
||||||
// stick our surface into mSurface, so that the Paint() path is the same.
|
// stick our surface into mSurface, so that the Paint() path is the same.
|
||||||
if (!aDestSurface) {
|
if (!aDestSurface) {
|
||||||
mSurface = resultSurf;
|
mDeprecatedSurface = resultSurf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyableCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
CopyableCanvasLayer::PaintWithOpacity(gfx::DrawTarget* aTarget,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
Layer* aMaskLayer,
|
SourceSurface* aMaskSurface,
|
||||||
gfxContext::GraphicsOperator aOperator)
|
gfx::CompositionOp aOperator)
|
||||||
{
|
{
|
||||||
if (!mSurface) {
|
if (!mSurface) {
|
||||||
NS_WARNING("No valid surface to draw!");
|
NS_WARNING("No valid surface to draw!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
|
SurfacePattern pat(mSurface, ExtendMode::CLAMP, Matrix(), ToFilter(mFilter));
|
||||||
|
|
||||||
|
Matrix oldTransform;
|
||||||
|
if (mNeedsYFlip) {
|
||||||
|
oldTransform = aTarget->GetTransform();
|
||||||
|
Matrix flipped = oldTransform;
|
||||||
|
flipped.Translate(0, mBounds.height);
|
||||||
|
flipped.Scale(1.0, -1.0);
|
||||||
|
aTarget->SetTransform(flipped);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawOptions options = DrawOptions(aOpacity, CompositionOp::OP_SOURCE);
|
||||||
|
|
||||||
|
// If content opaque, then save off current operator and set to source.
|
||||||
|
// This ensures that alpha is not applied even if the source surface
|
||||||
|
// has an alpha channel
|
||||||
|
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||||
|
options.mCompositionOp = CompositionOp::OP_SOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aOperator != CompositionOp::OP_OVER) {
|
||||||
|
options.mCompositionOp = aOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect rect = Rect(0, 0, mBounds.width, mBounds.height);
|
||||||
|
aTarget->FillRect(rect, pat, options);
|
||||||
|
if (aMaskSurface) {
|
||||||
|
aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNeedsYFlip) {
|
||||||
|
aTarget->SetTransform(oldTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CopyableCanvasLayer::DeprecatedPaintWithOpacity(gfxContext* aContext,
|
||||||
|
float aOpacity,
|
||||||
|
Layer* aMaskLayer,
|
||||||
|
gfxContext::GraphicsOperator aOperator)
|
||||||
|
{
|
||||||
|
if (!mDeprecatedSurface) {
|
||||||
|
NS_WARNING("No valid surface to draw!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<gfxPattern> pat = new gfxPattern(mDeprecatedSurface);
|
||||||
|
|
||||||
pat->SetFilter(mFilter);
|
pat->SetFilter(mFilter);
|
||||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||||
|
@ -216,27 +356,50 @@ CopyableCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxImageSurface*
|
DataSourceSurface*
|
||||||
CopyableCanvasLayer::GetTempSurface(const IntSize& aSize, const gfxImageFormat aFormat)
|
CopyableCanvasLayer::GetTempSurface(const IntSize& aSize,
|
||||||
|
const SurfaceFormat aFormat)
|
||||||
{
|
{
|
||||||
if (!mCachedTempSurface ||
|
if (!mCachedTempSurface ||
|
||||||
aSize.width != mCachedSize.width ||
|
aSize.width != mCachedSize.width ||
|
||||||
aSize.height != mCachedSize.height ||
|
aSize.height != mCachedSize.height ||
|
||||||
aFormat != mCachedFormat)
|
aFormat != mCachedFormat)
|
||||||
{
|
{
|
||||||
mCachedTempSurface = new gfxImageSurface(ThebesIntSize(aSize), aFormat);
|
mCachedTempSurface = Factory::CreateDataSourceSurface(aSize, aFormat);
|
||||||
mCachedSize = aSize;
|
mCachedSize = aSize;
|
||||||
mCachedFormat = aFormat;
|
mCachedFormat = aFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mCachedTempSurface->Stride() == mCachedTempSurface->Width() * 4);
|
MOZ_ASSERT(mCachedTempSurface->Stride() ==
|
||||||
|
mCachedTempSurface->GetSize().width * 4);
|
||||||
return mCachedTempSurface;
|
return mCachedTempSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfxImageSurface*
|
||||||
|
CopyableCanvasLayer::DeprecatedGetTempSurface(const IntSize& aSize,
|
||||||
|
const gfxImageFormat aFormat)
|
||||||
|
{
|
||||||
|
if (!mDeprecatedCachedTempSurface ||
|
||||||
|
aSize.width != mCachedSize.width ||
|
||||||
|
aSize.height != mCachedSize.height ||
|
||||||
|
aFormat != mDeprecatedCachedFormat)
|
||||||
|
{
|
||||||
|
mDeprecatedCachedTempSurface =
|
||||||
|
new gfxImageSurface(ThebesIntSize(aSize), aFormat);
|
||||||
|
mCachedSize = aSize;
|
||||||
|
mDeprecatedCachedFormat = aFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mDeprecatedCachedTempSurface->Stride() ==
|
||||||
|
mDeprecatedCachedTempSurface->Width() * 4);
|
||||||
|
return mDeprecatedCachedTempSurface;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyableCanvasLayer::DiscardTempSurface()
|
CopyableCanvasLayer::DiscardTempSurface()
|
||||||
{
|
{
|
||||||
mCachedTempSurface = nullptr;
|
mCachedTempSurface = nullptr;
|
||||||
|
mDeprecatedCachedTempSurface = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,15 +41,16 @@ public:
|
||||||
virtual bool IsDataValid(const Data& aData);
|
virtual bool IsDataValid(const Data& aData);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PaintWithOpacity(gfxContext* aContext,
|
void PaintWithOpacity(gfx::DrawTarget* aTarget,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
Layer* aMaskLayer,
|
gfx::SourceSurface* aMaskSurface,
|
||||||
gfxContext::GraphicsOperator aOperator = gfxContext::OPERATOR_OVER);
|
gfx::CompositionOp aOperator = gfx::CompositionOp::OP_OVER);
|
||||||
|
|
||||||
void UpdateSurface(gfxASurface* aDestSurface = nullptr,
|
void UpdateTarget(gfx::DrawTarget* aDestTarget = nullptr,
|
||||||
Layer* aMaskLayer = nullptr);
|
gfx::SourceSurface* aMaskSurface = nullptr);
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> mSurface;
|
RefPtr<gfx::SourceSurface> mSurface;
|
||||||
|
nsRefPtr<gfxASurface> mDeprecatedSurface;
|
||||||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||||
|
|
||||||
|
@ -59,13 +60,30 @@ protected:
|
||||||
bool mNeedsYFlip;
|
bool mNeedsYFlip;
|
||||||
bool mForceReadback;
|
bool mForceReadback;
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> mCachedTempSurface;
|
RefPtr<gfx::DataSourceSurface> mCachedTempSurface;
|
||||||
|
nsRefPtr<gfxImageSurface> mDeprecatedCachedTempSurface;
|
||||||
gfx::IntSize mCachedSize;
|
gfx::IntSize mCachedSize;
|
||||||
gfxImageFormat mCachedFormat;
|
gfx::SurfaceFormat mCachedFormat;
|
||||||
|
gfxImageFormat mDeprecatedCachedFormat;
|
||||||
|
|
||||||
gfxImageSurface* GetTempSurface(const gfx::IntSize& aSize, const gfxImageFormat aFormat);
|
gfx::DataSourceSurface* GetTempSurface(const gfx::IntSize& aSize,
|
||||||
|
const gfx::SurfaceFormat aFormat);
|
||||||
|
|
||||||
void DiscardTempSurface();
|
void DiscardTempSurface();
|
||||||
|
|
||||||
|
/* Deprecated thebes methods */
|
||||||
|
protected:
|
||||||
|
void DeprecatedPaintWithOpacity(gfxContext* aContext,
|
||||||
|
float aOpacity,
|
||||||
|
Layer* aMaskLayer,
|
||||||
|
gfxContext::GraphicsOperator aOperator = gfxContext::OPERATOR_OVER);
|
||||||
|
|
||||||
|
void DeprecatedUpdateSurface(gfxASurface* aDestSurface = nullptr,
|
||||||
|
Layer* aMaskLayer = nullptr);
|
||||||
|
|
||||||
|
gfxImageSurface* DeprecatedGetTempSurface(const gfx::IntSize& aSize,
|
||||||
|
const gfxImageFormat aFormat);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -710,8 +710,8 @@ class AutoLockImage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
|
AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
|
||||||
AutoLockImage(ImageContainer *aContainer, gfxASurface **aSurface) : mContainer(aContainer) {
|
AutoLockImage(ImageContainer *aContainer, RefPtr<gfx::SourceSurface> *aSurface) : mContainer(aContainer) {
|
||||||
*aSurface = mContainer->DeprecatedLockCurrentAsSurface(&mSize, getter_AddRefs(mImage)).get();
|
*aSurface = mContainer->LockCurrentAsSourceSurface(&mSize, getter_AddRefs(mImage));
|
||||||
}
|
}
|
||||||
~AutoLockImage() { if (mContainer) { mContainer->UnlockCurrentImage(); } }
|
~AutoLockImage() { if (mContainer) { mContainer->UnlockCurrentImage(); } }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* -*- Mode: c++; 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 "LayerUtils.h"
|
||||||
|
#include "PremultiplyTables.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
|
static inline const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
||||||
|
return PremultiplyTable[a*256+v];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
|
||||||
|
return UnpremultiplyTable[a*256+v];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PremultiplySurface(DataSourceSurface* srcSurface,
|
||||||
|
DataSourceSurface* destSurface)
|
||||||
|
{
|
||||||
|
if (!destSurface)
|
||||||
|
destSurface = srcSurface;
|
||||||
|
|
||||||
|
IntSize srcSize = srcSurface->GetSize();
|
||||||
|
MOZ_ASSERT(srcSurface->GetFormat() == destSurface->GetFormat() &&
|
||||||
|
srcSize.width == destSurface->GetSize().width &&
|
||||||
|
srcSize.height == destSurface->GetSize().height &&
|
||||||
|
srcSurface->Stride() == destSurface->Stride(),
|
||||||
|
"Source and destination surfaces don't have identical characteristics");
|
||||||
|
|
||||||
|
MOZ_ASSERT(srcSurface->Stride() == srcSize.width * 4,
|
||||||
|
"Source surface stride isn't tightly packed");
|
||||||
|
|
||||||
|
// Only premultiply ARGB32
|
||||||
|
if (srcSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
|
||||||
|
if (destSurface != srcSurface) {
|
||||||
|
memcpy(destSurface->GetData(), srcSurface->GetData(),
|
||||||
|
srcSurface->Stride() * srcSize.height);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *src = srcSurface->GetData();
|
||||||
|
uint8_t *dst = destSurface->GetData();
|
||||||
|
|
||||||
|
uint32_t dim = srcSize.width * srcSize.height;
|
||||||
|
for (uint32_t i = 0; i < dim; ++i) {
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
uint8_t b = *src++;
|
||||||
|
uint8_t g = *src++;
|
||||||
|
uint8_t r = *src++;
|
||||||
|
uint8_t a = *src++;
|
||||||
|
|
||||||
|
*dst++ = PremultiplyValue(a, b);
|
||||||
|
*dst++ = PremultiplyValue(a, g);
|
||||||
|
*dst++ = PremultiplyValue(a, r);
|
||||||
|
*dst++ = a;
|
||||||
|
#else
|
||||||
|
uint8_t a = *src++;
|
||||||
|
uint8_t r = *src++;
|
||||||
|
uint8_t g = *src++;
|
||||||
|
uint8_t b = *src++;
|
||||||
|
|
||||||
|
*dst++ = a;
|
||||||
|
*dst++ = PremultiplyValue(a, r);
|
||||||
|
*dst++ = PremultiplyValue(a, g);
|
||||||
|
*dst++ = PremultiplyValue(a, b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* -*- Mode: c++; 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/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_LAYERS_LAYERUTILS_H_
|
||||||
|
#define MOZILLA_LAYERS_LAYERUTILS_H_
|
||||||
|
|
||||||
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
void
|
||||||
|
PremultiplySurface(gfx::DataSourceSurface* srcSurface,
|
||||||
|
gfx::DataSourceSurface* destSurface = nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MOZILLA_LAYERS_LAYERUTILS_H_ */
|
|
@ -169,7 +169,7 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
|
||||||
mPostXScale(1.0f),
|
mPostXScale(1.0f),
|
||||||
mPostYScale(1.0f),
|
mPostYScale(1.0f),
|
||||||
mOpacity(1.0),
|
mOpacity(1.0),
|
||||||
mMixBlendMode(gfxContext::OPERATOR_OVER),
|
mMixBlendMode(CompositionOp::OP_OVER),
|
||||||
mForceIsolatedGroup(false),
|
mForceIsolatedGroup(false),
|
||||||
mContentFlags(0),
|
mContentFlags(0),
|
||||||
mUseClipRect(false),
|
mUseClipRect(false),
|
||||||
|
@ -670,20 +670,26 @@ Layer::GetEffectiveOpacity()
|
||||||
return opacity;
|
return opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxContext::GraphicsOperator
|
CompositionOp
|
||||||
Layer::GetEffectiveMixBlendMode()
|
Layer::GetEffectiveMixBlendMode()
|
||||||
{
|
{
|
||||||
if(mMixBlendMode != gfxContext::OPERATOR_OVER)
|
if(mMixBlendMode != CompositionOp::OP_OVER)
|
||||||
return mMixBlendMode;
|
return mMixBlendMode;
|
||||||
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
||||||
c = c->GetParent()) {
|
c = c->GetParent()) {
|
||||||
if(c->mMixBlendMode != gfxContext::OPERATOR_OVER)
|
if(c->mMixBlendMode != CompositionOp::OP_OVER)
|
||||||
return c->mMixBlendMode;
|
return c->mMixBlendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mMixBlendMode;
|
return mMixBlendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfxContext::GraphicsOperator
|
||||||
|
Layer::DeprecatedGetEffectiveMixBlendMode()
|
||||||
|
{
|
||||||
|
return ThebesOp(GetEffectiveMixBlendMode());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Layer::ComputeEffectiveTransformForMaskLayer(const Matrix4x4& aTransformToSurface)
|
Layer::ComputeEffectiveTransformForMaskLayer(const Matrix4x4& aTransformToSurface)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "GraphicsFilter.h" // for GraphicsFilter
|
#include "GraphicsFilter.h" // for GraphicsFilter
|
||||||
#include "gfxPoint.h" // for gfxPoint
|
#include "gfxPoint.h" // for gfxPoint
|
||||||
#include "gfxRect.h" // for gfxRect
|
#include "gfxRect.h" // for gfxRect
|
||||||
|
#include "gfx2DGlue.h"
|
||||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
|
||||||
#include "mozilla/DebugOnly.h" // for DebugOnly
|
#include "mozilla/DebugOnly.h" // for DebugOnly
|
||||||
#include "mozilla/EventForwards.h" // for nsPaintEvent
|
#include "mozilla/EventForwards.h" // for nsPaintEvent
|
||||||
|
@ -786,7 +787,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode)
|
void SetMixBlendMode(gfx::CompositionOp aMixBlendMode)
|
||||||
{
|
{
|
||||||
if (mMixBlendMode != aMixBlendMode) {
|
if (mMixBlendMode != aMixBlendMode) {
|
||||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this));
|
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this));
|
||||||
|
@ -795,6 +796,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeprecatedSetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode)
|
||||||
|
{
|
||||||
|
SetMixBlendMode(gfx::CompositionOpForOp(aMixBlendMode));
|
||||||
|
}
|
||||||
|
|
||||||
void SetForceIsolatedGroup(bool aForceIsolatedGroup)
|
void SetForceIsolatedGroup(bool aForceIsolatedGroup)
|
||||||
{
|
{
|
||||||
if(mForceIsolatedGroup != aForceIsolatedGroup) {
|
if(mForceIsolatedGroup != aForceIsolatedGroup) {
|
||||||
|
@ -1033,7 +1039,7 @@ public:
|
||||||
|
|
||||||
// These getters can be used anytime.
|
// These getters can be used anytime.
|
||||||
float GetOpacity() { return mOpacity; }
|
float GetOpacity() { return mOpacity; }
|
||||||
gfxContext::GraphicsOperator GetMixBlendMode() const { return mMixBlendMode; }
|
gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
|
||||||
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
|
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
|
||||||
uint32_t GetContentFlags() { return mContentFlags; }
|
uint32_t GetContentFlags() { return mContentFlags; }
|
||||||
const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
|
const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
|
||||||
|
@ -1207,7 +1213,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the blendmode of this layer.
|
* Returns the blendmode of this layer.
|
||||||
*/
|
*/
|
||||||
gfxContext::GraphicsOperator GetEffectiveMixBlendMode();
|
gfx::CompositionOp GetEffectiveMixBlendMode();
|
||||||
|
gfxContext::GraphicsOperator DeprecatedGetEffectiveMixBlendMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns the effective transform computed by
|
* This returns the effective transform computed by
|
||||||
|
@ -1408,7 +1415,7 @@ protected:
|
||||||
AnimationArray mAnimations;
|
AnimationArray mAnimations;
|
||||||
InfallibleTArray<AnimData> mAnimationData;
|
InfallibleTArray<AnimData> mAnimationData;
|
||||||
float mOpacity;
|
float mOpacity;
|
||||||
gfxContext::GraphicsOperator mMixBlendMode;
|
gfx::CompositionOp mMixBlendMode;
|
||||||
bool mForceIsolatedGroup;
|
bool mForceIsolatedGroup;
|
||||||
nsIntRect mClipRect;
|
nsIntRect mClipRect;
|
||||||
nsIntRect mTileSourceRect;
|
nsIntRect mTileSourceRect;
|
||||||
|
|
|
@ -13,3 +13,6 @@ CXXFLAGS += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
|
CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
|
||||||
|
|
||||||
|
PremultiplyTables.h: $(srcdir)/genTables.py
|
||||||
|
$(PYTHON) $(srcdir)/genTables.py
|
||||||
|
|
|
@ -301,9 +301,17 @@ RotatedContentBuffer::BufferContentType()
|
||||||
bool
|
bool
|
||||||
RotatedContentBuffer::BufferSizeOkFor(const nsIntSize& aSize)
|
RotatedContentBuffer::BufferSizeOkFor(const nsIntSize& aSize)
|
||||||
{
|
{
|
||||||
return (aSize == mBufferRect.Size() ||
|
if (aSize == mBufferRect.Size()) {
|
||||||
(SizedToVisibleBounds != mBufferSizePolicy &&
|
return true;
|
||||||
aSize < mBufferRect.Size()));
|
}
|
||||||
|
|
||||||
|
if (SizedToVisibleBounds != mBufferSizePolicy &&
|
||||||
|
aSize < mBufferRect.Size()) {
|
||||||
|
return (aSize.width * 2 > mBufferRect.width) &&
|
||||||
|
(aSize.height * 2 > mBufferRect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -503,8 +511,9 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer,
|
||||||
// or call CreateBuffer before this call.
|
// or call CreateBuffer before this call.
|
||||||
FinalizeFrame(result.mRegionToDraw);
|
FinalizeFrame(result.mRegionToDraw);
|
||||||
|
|
||||||
if (result.mRegionToDraw.IsEmpty())
|
if (result.mRegionToDraw.IsEmpty()) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
|
nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
|
||||||
RefPtr<DrawTarget> destDTBuffer;
|
RefPtr<DrawTarget> destDTBuffer;
|
||||||
|
@ -614,7 +623,7 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer,
|
||||||
mBufferRotation = nsIntPoint(0,0);
|
mBufferRotation = nsIntPoint(0,0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The buffer's not big enough, so allocate a new one
|
// The buffer's not big enough or the buffer needs to shrink, so allocate a new one
|
||||||
CreateBuffer(result.mContentType, destBufferRect, bufferFlags,
|
CreateBuffer(result.mContentType, destBufferRect, bufferFlags,
|
||||||
&destDTBuffer, &destDTBufferOnWhite);
|
&destDTBuffer, &destDTBufferOnWhite);
|
||||||
if (!destDTBuffer) {
|
if (!destDTBuffer) {
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed
|
#include "nsCOMPtr.h" // for already_AddRefed
|
||||||
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
||||||
|
#include "gfx2DGlue.h"
|
||||||
|
|
||||||
class gfxContext;
|
class gfxContext;
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
@ -18,17 +20,39 @@ namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
BasicCanvasLayer::Paint(DrawTarget* aTarget, SourceSurface* aMaskSurface)
|
||||||
{
|
{
|
||||||
if (IsHidden())
|
if (IsHidden())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FirePreTransactionCallback();
|
FirePreTransactionCallback();
|
||||||
UpdateSurface();
|
UpdateTarget();
|
||||||
FireDidTransactionCallback();
|
FireDidTransactionCallback();
|
||||||
|
|
||||||
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
|
CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
|
||||||
PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
|
PaintWithOpacity(aTarget,
|
||||||
|
GetEffectiveOpacity(),
|
||||||
|
aMaskSurface,
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicCanvasLayer::DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer)
|
||||||
|
{
|
||||||
|
if (IsHidden())
|
||||||
|
return;
|
||||||
|
|
||||||
|
FirePreTransactionCallback();
|
||||||
|
DeprecatedUpdateSurface();
|
||||||
|
FireDidTransactionCallback();
|
||||||
|
|
||||||
|
gfxContext::GraphicsOperator mixBlendMode = DeprecatedGetEffectiveMixBlendMode();
|
||||||
|
DeprecatedPaintWithOpacity(aContext,
|
||||||
|
GetEffectiveOpacity(),
|
||||||
|
aMaskLayer,
|
||||||
|
mixBlendMode != gfxContext::OPERATOR_OVER ?
|
||||||
|
mixBlendMode :
|
||||||
|
DeprecatedGetOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<CanvasLayer>
|
already_AddRefed<CanvasLayer>
|
||||||
|
|
|
@ -34,7 +34,9 @@ public:
|
||||||
CanvasLayer::SetVisibleRegion(aRegion);
|
CanvasLayer::SetVisibleRegion(aRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
virtual void Paint(gfx::DrawTarget* aTarget,
|
||||||
|
gfx::SourceSurface* aMaskSurface);
|
||||||
|
virtual void DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BasicLayerManager* BasicManager()
|
BasicLayerManager* BasicManager()
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "BasicLayers.h" // for BasicLayerManager
|
#include "BasicLayers.h" // for BasicLayerManager
|
||||||
#include "gfxContext.h" // for gfxContext, etc
|
#include "gfxContext.h" // for gfxContext, etc
|
||||||
#include "gfxRect.h" // for gfxRect
|
#include "gfxRect.h" // for gfxRect
|
||||||
|
#include "gfx2DGlue.h"
|
||||||
#include "mozilla/mozalloc.h" // for operator new
|
#include "mozilla/mozalloc.h" // for operator new
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed
|
#include "nsCOMPtr.h" // for already_AddRefed
|
||||||
|
@ -43,13 +44,35 @@ public:
|
||||||
ColorLayer::SetVisibleRegion(aRegion);
|
ColorLayer::SetVisibleRegion(aRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer)
|
virtual void Paint(DrawTarget* aTarget, SourceSurface* aMaskSurface)
|
||||||
{
|
{
|
||||||
if (IsHidden())
|
if (IsHidden()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
|
||||||
|
CompositionOp op =
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator();
|
||||||
|
|
||||||
|
DrawOptions opts = DrawOptions();
|
||||||
|
opts.mCompositionOp = op;
|
||||||
|
ColorPattern pattern(ToColor(mColor));
|
||||||
|
aTarget->MaskSurface(pattern,
|
||||||
|
aMaskSurface,
|
||||||
|
ToIntRect(GetBounds()).TopLeft(),
|
||||||
|
opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer)
|
||||||
|
{
|
||||||
|
if (IsHidden()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
gfxContextAutoSaveRestore contextSR(aContext);
|
gfxContextAutoSaveRestore contextSR(aContext);
|
||||||
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
|
gfxContext::GraphicsOperator mixBlendMode = DeprecatedGetEffectiveMixBlendMode();
|
||||||
AutoSetOperator setOptimizedOperator(aContext, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
|
AutoSetOperator setOptimizedOperator(aContext,
|
||||||
|
mixBlendMode != gfxContext::OPERATOR_OVER ?
|
||||||
|
mixBlendMode :
|
||||||
|
DeprecatedGetOperator());
|
||||||
|
|
||||||
aContext->SetColor(mColor);
|
aContext->SetColor(mColor);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur
|
||||||
Layer* child = GetFirstChild();
|
Layer* child = GetFirstChild();
|
||||||
bool hasSingleBlendingChild = false;
|
bool hasSingleBlendingChild = false;
|
||||||
if (!HasMultipleChildren() && child) {
|
if (!HasMultipleChildren() && child) {
|
||||||
hasSingleBlendingChild = child->GetMixBlendMode() != gfxContext::OPERATOR_OVER;
|
hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a single childand it is not blending,, it can just inherit our opacity,
|
/* If we have a single childand it is not blending,, it can just inherit our opacity,
|
||||||
|
@ -72,7 +72,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur
|
||||||
mUseIntermediateSurface =
|
mUseIntermediateSurface =
|
||||||
GetMaskLayer() ||
|
GetMaskLayer() ||
|
||||||
GetForceIsolatedGroup() ||
|
GetForceIsolatedGroup() ||
|
||||||
(GetMixBlendMode() != gfxContext::OPERATOR_OVER && HasMultipleChildren()) ||
|
(GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
|
||||||
(GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild));
|
(GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@ public:
|
||||||
ImageLayer::SetVisibleRegion(aRegion);
|
ImageLayer::SetVisibleRegion(aRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
virtual void Paint(DrawTarget* aTarget, SourceSurface* aMaskSurface);
|
||||||
|
virtual void DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer);
|
||||||
|
|
||||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||||
SurfaceDescriptor* aDescriptor);
|
SurfaceDescriptor* aDescriptor);
|
||||||
|
@ -64,43 +65,104 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// only paints the image if aContext is non-null
|
// only paints the image if aContext is non-null
|
||||||
already_AddRefed<gfxPattern>
|
void
|
||||||
GetAndPaintCurrentImage(gfxContext* aContext,
|
GetAndPaintCurrentImage(DrawTarget* aTarget,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
Layer* aMaskLayer);
|
SourceSurface* aMaskSurface);
|
||||||
|
already_AddRefed<gfxPattern>
|
||||||
|
DeprecatedGetAndPaintCurrentImage(gfxContext* aContext,
|
||||||
|
float aOpacity,
|
||||||
|
Layer* aMaskLayer);
|
||||||
|
|
||||||
gfx::IntSize mSize;
|
gfx::IntSize mSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
DeprecatedPaintContext(gfxPattern* aPattern,
|
||||||
|
const nsIntRegion& aVisible,
|
||||||
|
float aOpacity,
|
||||||
|
gfxContext* aContext,
|
||||||
|
Layer* aMaskLayer);
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
BasicImageLayer::Paint(DrawTarget* aTarget, SourceSurface* aMaskSurface)
|
||||||
{
|
{
|
||||||
if (IsHidden())
|
if (IsHidden()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
GetAndPaintCurrentImage(aTarget, GetEffectiveOpacity(), aMaskSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicImageLayer::DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer)
|
||||||
|
{
|
||||||
|
if (IsHidden()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
nsRefPtr<gfxPattern> dontcare =
|
nsRefPtr<gfxPattern> dontcare =
|
||||||
GetAndPaintCurrentImage(aContext, GetEffectiveOpacity(), aMaskLayer);
|
DeprecatedGetAndPaintCurrentImage(aContext,
|
||||||
|
GetEffectiveOpacity(),
|
||||||
|
aMaskLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicImageLayer::GetAndPaintCurrentImage(DrawTarget* aTarget,
|
||||||
|
float aOpacity,
|
||||||
|
SourceSurface* aMaskSurface)
|
||||||
|
{
|
||||||
|
if (!mContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mContainer->SetImageFactory(mManager->IsCompositingCheap() ?
|
||||||
|
nullptr :
|
||||||
|
BasicManager()->GetImageFactory());
|
||||||
|
IntSize size;
|
||||||
|
Image* image = nullptr;
|
||||||
|
RefPtr<SourceSurface> surf =
|
||||||
|
mContainer->LockCurrentAsSourceSurface(&size, &image);
|
||||||
|
|
||||||
|
if (!surf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aTarget) {
|
||||||
|
// The visible region can extend outside the image, so just draw
|
||||||
|
// within the image bounds.
|
||||||
|
SurfacePattern pat(surf, ExtendMode::CLAMP, Matrix(), ToFilter(mFilter));
|
||||||
|
CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
|
||||||
|
CompositionOp op =
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator();
|
||||||
|
DrawOptions opts(aOpacity, op);
|
||||||
|
|
||||||
|
aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), opts);
|
||||||
|
|
||||||
|
GetContainer()->NotifyPaintedImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
mContainer->UnlockCurrentImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<gfxPattern>
|
already_AddRefed<gfxPattern>
|
||||||
BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
BasicImageLayer::DeprecatedGetAndPaintCurrentImage(gfxContext* aContext,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
Layer* aMaskLayer)
|
Layer* aMaskLayer)
|
||||||
{
|
{
|
||||||
if (!mContainer)
|
if (!mContainer)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nullptr : BasicManager()->GetImageFactory());
|
mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nullptr : BasicManager()->GetImageFactory());
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surface;
|
RefPtr<gfx::SourceSurface> surface;
|
||||||
AutoLockImage autoLock(mContainer, getter_AddRefs(surface));
|
AutoLockImage autoLock(mContainer, &surface);
|
||||||
Image *image = autoLock.GetImage();
|
Image *image = autoLock.GetImage();
|
||||||
gfx::IntSize size = mSize = autoLock.GetSize();
|
gfx::IntSize size = mSize = autoLock.GetSize();
|
||||||
|
|
||||||
if (!surface || surface->CairoStatus()) {
|
if (!surface || !surface->IsValid()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
nsRefPtr<gfxPattern> pat = new gfxPattern(surface, gfx::Matrix());
|
||||||
if (!pat) {
|
if (!pat) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -110,10 +172,12 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||||
// The visible region can extend outside the image, so just draw
|
// The visible region can extend outside the image, so just draw
|
||||||
// within the image bounds.
|
// within the image bounds.
|
||||||
if (aContext) {
|
if (aContext) {
|
||||||
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
|
CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
|
||||||
AutoSetOperator setOptimizedOperator(aContext, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
|
CompositionOp op =
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator();
|
||||||
|
AutoSetOperator setOptimizedOperator(aContext, ThebesOp(op));
|
||||||
|
|
||||||
PaintContext(pat,
|
DeprecatedPaintContext(pat,
|
||||||
nsIntRegion(nsIntRect(0, 0, size.width, size.height)),
|
nsIntRegion(nsIntRect(0, 0, size.width, size.height)),
|
||||||
aOpacity, aContext, aMaskLayer);
|
aOpacity, aContext, aMaskLayer);
|
||||||
|
|
||||||
|
@ -123,12 +187,12 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||||
return pat.forget();
|
return pat.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
PaintContext(gfxPattern* aPattern,
|
DeprecatedPaintContext(gfxPattern* aPattern,
|
||||||
const nsIntRegion& aVisible,
|
const nsIntRegion& aVisible,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
Layer* aMaskLayer)
|
Layer* aMaskLayer)
|
||||||
{
|
{
|
||||||
// Set PAD mode so that when the video is being scaled, we do not sample
|
// Set PAD mode so that when the video is being scaled, we do not sample
|
||||||
// outside the bounds of the video image.
|
// outside the bounds of the video image.
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "gfxContext.h" // for gfxContext, etc
|
#include "gfxContext.h" // for gfxContext, etc
|
||||||
#include "nsDebug.h" // for NS_ASSERTION
|
#include "nsDebug.h" // for NS_ASSERTION
|
||||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||||
|
#include "mozilla/gfx/Types.h"
|
||||||
|
|
||||||
class gfxASurface;
|
class gfxASurface;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
@ -44,7 +46,7 @@ public:
|
||||||
BasicImplData() : mHidden(false),
|
BasicImplData() : mHidden(false),
|
||||||
mClipToVisibleRegion(false),
|
mClipToVisibleRegion(false),
|
||||||
mDrawAtomically(false),
|
mDrawAtomically(false),
|
||||||
mOperator(gfxContext::OPERATOR_OVER)
|
mOperator(gfx::CompositionOp::OP_OVER)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(BasicImplData);
|
MOZ_COUNT_CTOR(BasicImplData);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +61,9 @@ public:
|
||||||
* set up to account for all the properties of the layer (transform,
|
* set up to account for all the properties of the layer (transform,
|
||||||
* opacity, etc).
|
* opacity, etc).
|
||||||
*/
|
*/
|
||||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer) {}
|
virtual void Paint(gfx::DrawTarget* aTarget,
|
||||||
|
gfx::SourceSurface* aMaskSurface) {}
|
||||||
|
virtual void DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like Paint() but called for ThebesLayers with the additional parameters
|
* Like Paint() but called for ThebesLayers with the additional parameters
|
||||||
|
@ -94,14 +98,19 @@ public:
|
||||||
* the operator to be used when compositing the layer in this transaction. It must
|
* the operator to be used when compositing the layer in this transaction. It must
|
||||||
* be OVER or SOURCE.
|
* be OVER or SOURCE.
|
||||||
*/
|
*/
|
||||||
void SetOperator(gfxContext::GraphicsOperator aOperator)
|
void SetOperator(gfx::CompositionOp aOperator)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aOperator == gfxContext::OPERATOR_OVER ||
|
NS_ASSERTION(aOperator == gfx::CompositionOp::OP_OVER ||
|
||||||
aOperator == gfxContext::OPERATOR_SOURCE,
|
aOperator == gfx::CompositionOp::OP_SOURCE,
|
||||||
"Bad composition operator");
|
"Bad composition operator");
|
||||||
mOperator = aOperator;
|
mOperator = aOperator;
|
||||||
}
|
}
|
||||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
|
||||||
|
gfx::CompositionOp GetOperator() const { return mOperator; }
|
||||||
|
gfxContext::GraphicsOperator DeprecatedGetOperator() const
|
||||||
|
{
|
||||||
|
return gfx::ThebesOp(mOperator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a surface for this layer. Will use an existing surface, if
|
* Return a surface for this layer. Will use an existing surface, if
|
||||||
|
@ -123,7 +132,7 @@ protected:
|
||||||
bool mHidden;
|
bool mHidden;
|
||||||
bool mClipToVisibleRegion;
|
bool mClipToVisibleRegion;
|
||||||
bool mDrawAtomically;
|
bool mDrawAtomically;
|
||||||
gfxContext::GraphicsOperator mOperator;
|
gfx::CompositionOp mOperator;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // layers
|
} // layers
|
||||||
|
|
|
@ -415,7 +415,7 @@ MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicImplData* data = ToData(aLayer);
|
BasicImplData* data = ToData(aLayer);
|
||||||
data->SetOperator(gfxContext::OPERATOR_OVER);
|
data->SetOperator(CompositionOp::OP_OVER);
|
||||||
data->SetClipToVisibleRegion(false);
|
data->SetClipToVisibleRegion(false);
|
||||||
data->SetDrawAtomically(false);
|
data->SetDrawAtomically(false);
|
||||||
|
|
||||||
|
@ -500,13 +500,13 @@ ApplyDoubleBuffering(Layer* aLayer, const nsIntRect& aVisibleRect)
|
||||||
// using OPERATOR_SOURCE to ensure that alpha values in a transparent window
|
// using OPERATOR_SOURCE to ensure that alpha values in a transparent window
|
||||||
// are cleared. This can also be faster than OPERATOR_OVER.
|
// are cleared. This can also be faster than OPERATOR_OVER.
|
||||||
if (!container) {
|
if (!container) {
|
||||||
data->SetOperator(gfxContext::OPERATOR_SOURCE);
|
data->SetOperator(CompositionOp::OP_SOURCE);
|
||||||
data->SetDrawAtomically(true);
|
data->SetDrawAtomically(true);
|
||||||
} else {
|
} else {
|
||||||
if (container->UseIntermediateSurface() ||
|
if (container->UseIntermediateSurface() ||
|
||||||
!container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
|
!container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
|
||||||
// We need to double-buffer this container.
|
// We need to double-buffer this container.
|
||||||
data->SetOperator(gfxContext::OPERATOR_SOURCE);
|
data->SetOperator(CompositionOp::OP_SOURCE);
|
||||||
container->ForceIntermediateSurface();
|
container->ForceIntermediateSurface();
|
||||||
} else {
|
} else {
|
||||||
// Tell the children to clip to their visible regions so our assumption
|
// Tell the children to clip to their visible regions so our assumption
|
||||||
|
@ -824,7 +824,7 @@ BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
|
||||||
aPaintContext.mCallback, aPaintContext.mCallbackData,
|
aPaintContext.mCallback, aPaintContext.mCallbackData,
|
||||||
aPaintContext.mReadback);
|
aPaintContext.mReadback);
|
||||||
} else {
|
} else {
|
||||||
data->Paint(aGroupTarget, aPaintContext.mLayer->GetMaskLayer());
|
data->DeprecatedPaint(aGroupTarget, aPaintContext.mLayer->GetMaskLayer());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ReadbackProcessor readback;
|
ReadbackProcessor readback;
|
||||||
|
@ -862,7 +862,8 @@ BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipT
|
||||||
aPaintContext.mLayer->GetEffectiveVisibleRegion());
|
aPaintContext.mLayer->GetEffectiveVisibleRegion());
|
||||||
}
|
}
|
||||||
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aPaintContext.mLayer);
|
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aPaintContext.mLayer);
|
||||||
AutoSetOperator setOperator(aPaintContext.mTarget, container->GetOperator());
|
AutoSetOperator setOperator(aPaintContext.mTarget,
|
||||||
|
ThebesOp(container->GetOperator()));
|
||||||
PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
|
PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
|
||||||
aPaintContext.mLayer->GetMaskLayer());
|
aPaintContext.mLayer->GetMaskLayer());
|
||||||
}
|
}
|
||||||
|
@ -896,7 +897,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||||
bool needsClipToVisibleRegion =
|
bool needsClipToVisibleRegion =
|
||||||
data->GetClipToVisibleRegion() && !aLayer->AsThebesLayer();
|
data->GetClipToVisibleRegion() && !aLayer->AsThebesLayer();
|
||||||
NS_ASSERTION(needsGroup || !aLayer->GetFirstChild() ||
|
NS_ASSERTION(needsGroup || !aLayer->GetFirstChild() ||
|
||||||
container->GetOperator() == gfxContext::OPERATOR_OVER,
|
container->GetOperator() == CompositionOp::OP_OVER,
|
||||||
"non-OVER operator should have forced UseIntermediateSurface");
|
"non-OVER operator should have forced UseIntermediateSurface");
|
||||||
NS_ASSERTION(!aLayer->GetFirstChild() || !aLayer->GetMaskLayer() ||
|
NS_ASSERTION(!aLayer->GetFirstChild() || !aLayer->GetMaskLayer() ||
|
||||||
container->UseIntermediateSurface(),
|
container->UseIntermediateSurface(),
|
||||||
|
|
|
@ -197,13 +197,6 @@ protected:
|
||||||
bool mCompositorMightResample;
|
bool mCompositorMightResample;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
PaintContext(gfxPattern* aPattern,
|
|
||||||
const nsIntRegion& aVisible,
|
|
||||||
float aOpacity,
|
|
||||||
gfxContext* aContext,
|
|
||||||
Layer* aMaskLayer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
float opacity = GetEffectiveOpacity();
|
float opacity = GetEffectiveOpacity();
|
||||||
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
|
CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
|
||||||
|
|
||||||
if (!BasicManager()->IsRetained()) {
|
if (!BasicManager()->IsRetained()) {
|
||||||
NS_ASSERTION(readbackUpdates.IsEmpty(), "Can't do readback for non-retained layer");
|
NS_ASSERTION(readbackUpdates.IsEmpty(), "Can't do readback for non-retained layer");
|
||||||
|
@ -83,14 +83,17 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||||
aContext->Save();
|
aContext->Save();
|
||||||
|
|
||||||
bool needsClipToVisibleRegion = GetClipToVisibleRegion();
|
bool needsClipToVisibleRegion = GetClipToVisibleRegion();
|
||||||
bool needsGroup =
|
bool needsGroup = opacity != 1.0 ||
|
||||||
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER || mixBlendMode != gfxContext::OPERATOR_OVER || aMaskLayer;
|
GetOperator() != CompositionOp::OP_OVER ||
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ||
|
||||||
|
aMaskLayer;
|
||||||
nsRefPtr<gfxContext> groupContext;
|
nsRefPtr<gfxContext> groupContext;
|
||||||
if (needsGroup) {
|
if (needsGroup) {
|
||||||
groupContext =
|
groupContext =
|
||||||
BasicManager()->PushGroupForLayer(aContext, this, toDraw,
|
BasicManager()->PushGroupForLayer(aContext, this, toDraw,
|
||||||
&needsClipToVisibleRegion);
|
&needsClipToVisibleRegion);
|
||||||
if (GetOperator() != gfxContext::OPERATOR_OVER || mixBlendMode != gfxContext::OPERATOR_OVER) {
|
if (GetOperator() != CompositionOp::OP_OVER ||
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER) {
|
||||||
needsClipToVisibleRegion = true;
|
needsClipToVisibleRegion = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,7 +106,9 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||||
if (needsClipToVisibleRegion) {
|
if (needsClipToVisibleRegion) {
|
||||||
gfxUtils::ClipToRegion(aContext, toDraw);
|
gfxUtils::ClipToRegion(aContext, toDraw);
|
||||||
}
|
}
|
||||||
AutoSetOperator setOptimizedOperator(aContext, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
|
CompositionOp op =
|
||||||
|
mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator();
|
||||||
|
AutoSetOperator setOptimizedOperator(aContext, ThebesOp(op));
|
||||||
PaintWithMask(aContext, opacity, aMaskLayer);
|
PaintWithMask(aContext, opacity, aMaskLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +137,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||||
|
|
||||||
if (!IsHidden() && !clipExtents.IsEmpty()) {
|
if (!IsHidden() && !clipExtents.IsEmpty()) {
|
||||||
mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
|
mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
|
||||||
CompositionOpForOp(GetOperator()),
|
GetOperator(),
|
||||||
maskSurface, &maskTransform);
|
maskSurface, &maskTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surface = mBuffer->AsTextureClientSurface()->GetAsSurface();
|
RefPtr<DrawTarget> drawTarget =
|
||||||
if (surface) {
|
mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
|
||||||
aLayer->UpdateSurface(surface);
|
if (drawTarget) {
|
||||||
|
aLayer->UpdateTarget(drawTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
mBuffer->Unlock();
|
mBuffer->Unlock();
|
||||||
|
@ -88,7 +89,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface) {
|
if (drawTarget) {
|
||||||
GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
|
GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
|
||||||
GetForwarder()->UseTexture(this, mBuffer);
|
GetForwarder()->UseTexture(this, mBuffer);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +216,7 @@ DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxASurface* surface = mDeprecatedTextureClient->LockSurface();
|
gfxASurface* surface = mDeprecatedTextureClient->LockSurface();
|
||||||
aLayer->UpdateSurface(surface);
|
aLayer->DeprecatedUpdateSurface(surface);
|
||||||
mDeprecatedTextureClient->Unlock();
|
mDeprecatedTextureClient->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,8 @@ protected:
|
||||||
return mImageClientTypeContainer;
|
return mImageClientTypeContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surface;
|
RefPtr<gfx::SourceSurface> surface;
|
||||||
AutoLockImage autoLock(mContainer, getter_AddRefs(surface));
|
AutoLockImage autoLock(mContainer, &surface);
|
||||||
|
|
||||||
mImageClientTypeContainer = autoLock.GetImage() ?
|
mImageClientTypeContainer = autoLock.GetImage() ?
|
||||||
BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN;
|
BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN;
|
||||||
|
|
|
@ -216,10 +216,10 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||||
|
|
||||||
GetForwarder()->UseTexture(this, mFrontBuffer);
|
GetForwarder()->UseTexture(this, mFrontBuffer);
|
||||||
} else {
|
} else {
|
||||||
nsRefPtr<gfxASurface> surface = image->DeprecatedGetAsSurface();
|
RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
|
||||||
MOZ_ASSERT(surface);
|
MOZ_ASSERT(surface);
|
||||||
|
|
||||||
gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
|
gfx::IntSize size = image->GetSize();
|
||||||
|
|
||||||
if (mFrontBuffer &&
|
if (mFrontBuffer &&
|
||||||
(mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
|
(mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
|
||||||
|
@ -230,7 +230,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||||
bool bufferCreated = false;
|
bool bufferCreated = false;
|
||||||
if (!mFrontBuffer) {
|
if (!mFrontBuffer) {
|
||||||
gfxImageFormat format
|
gfxImageFormat format
|
||||||
= gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
|
= gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat()));
|
||||||
mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
|
mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
|
||||||
mTextureFlags);
|
mTextureFlags);
|
||||||
MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget());
|
MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget());
|
||||||
|
@ -249,9 +249,8 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||||
{
|
{
|
||||||
// We must not keep a reference to the DrawTarget after it has been unlocked.
|
// We must not keep a reference to the DrawTarget after it has been unlocked.
|
||||||
RefPtr<DrawTarget> dt = mFrontBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
|
RefPtr<DrawTarget> dt = mFrontBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
|
||||||
RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surface);
|
MOZ_ASSERT(surface.get());
|
||||||
MOZ_ASSERT(source.get());
|
dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint());
|
||||||
dt->CopySurface(source, IntRect(IntPoint(), source->GetSize()), IntPoint());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mFrontBuffer->Unlock();
|
mFrontBuffer->Unlock();
|
||||||
|
|
|
@ -82,25 +82,12 @@ CanvasLayerD3D10::Initialize(const Data& aData)
|
||||||
|
|
||||||
// XXX we should store mDrawTarget and use it directly in UpdateSurface,
|
// XXX we should store mDrawTarget and use it directly in UpdateSurface,
|
||||||
// bypassing Thebes
|
// bypassing Thebes
|
||||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
mSurface = mDrawTarget->Snapshot();
|
||||||
} else {
|
} else {
|
||||||
NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
|
NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
|
||||||
}
|
}
|
||||||
|
|
||||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||||
|
|
||||||
if (mSurface && mSurface->GetType() == gfxSurfaceType::D2D) {
|
|
||||||
void *data = mSurface->GetData(&gKeyD3D10Texture);
|
|
||||||
if (data) {
|
|
||||||
mTexture = static_cast<ID3D10Texture2D*>(data);
|
|
||||||
mIsD2DTexture = true;
|
|
||||||
device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
|
|
||||||
mHasAlpha =
|
|
||||||
mSurface->GetContentType() == gfxContentType::COLOR_ALPHA;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsD2DTexture = false;
|
mIsD2DTexture = false;
|
||||||
|
|
||||||
// Create a texture in case we need to readback.
|
// Create a texture in case we need to readback.
|
||||||
|
@ -127,7 +114,6 @@ CanvasLayerD3D10::UpdateSurface()
|
||||||
if (mDrawTarget) {
|
if (mDrawTarget) {
|
||||||
mDrawTarget->Flush();
|
mDrawTarget->Flush();
|
||||||
} else if (mIsD2DTexture) {
|
} else if (mIsD2DTexture) {
|
||||||
mSurface->Flush();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,12 +165,6 @@ CanvasLayerD3D10::UpdateSurface()
|
||||||
MOZ_CRASH("Unhandled SharedSurfaceType.");
|
MOZ_CRASH("Unhandled SharedSurfaceType.");
|
||||||
}
|
}
|
||||||
} else if (mSurface) {
|
} else if (mSurface) {
|
||||||
RECT r;
|
|
||||||
r.left = 0;
|
|
||||||
r.top = 0;
|
|
||||||
r.right = mBounds.width;
|
|
||||||
r.bottom = mBounds.height;
|
|
||||||
|
|
||||||
D3D10_MAPPED_TEXTURE2D map;
|
D3D10_MAPPED_TEXTURE2D map;
|
||||||
HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map);
|
HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map);
|
||||||
|
|
||||||
|
@ -193,17 +173,13 @@ CanvasLayerD3D10::UpdateSurface()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> dstSurface;
|
RefPtr<DrawTarget> destTarget =
|
||||||
|
Factory::CreateDrawTargetForD3D10Texture(mTexture,
|
||||||
|
SurfaceFormat::R8G8B8A8);
|
||||||
|
Rect r(Point(0, 0), ToRect(mBounds).Size());
|
||||||
|
destTarget->DrawSurface(mSurface, r, r, DrawSurfaceOptions(),
|
||||||
|
DrawOptions(1.0F, CompositionOp::OP_SOURCE));
|
||||||
|
|
||||||
dstSurface = new gfxImageSurface((unsigned char*)map.pData,
|
|
||||||
gfxIntSize(mBounds.width, mBounds.height),
|
|
||||||
map.RowPitch,
|
|
||||||
gfxImageFormat::ARGB32);
|
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(dstSurface);
|
|
||||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
||||||
ctx->SetSource(mSurface);
|
|
||||||
ctx->Paint();
|
|
||||||
|
|
||||||
mTexture->Unmap(0);
|
mTexture->Unmap(0);
|
||||||
mSRView = mUploadSRView;
|
mSRView = mUploadSRView;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ private:
|
||||||
|
|
||||||
void UpdateSurface();
|
void UpdateSurface();
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> mSurface;
|
RefPtr<gfx::SourceSurface> mSurface;
|
||||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||||
nsRefPtr<GLContext> mGLContext;
|
nsRefPtr<GLContext> mGLContext;
|
||||||
nsRefPtr<ID3D10Texture2D> mTexture;
|
nsRefPtr<ID3D10Texture2D> mTexture;
|
||||||
|
|
|
@ -42,11 +42,10 @@ CanvasLayerD3D9::~CanvasLayerD3D9()
|
||||||
void
|
void
|
||||||
CanvasLayerD3D9::Initialize(const Data& aData)
|
CanvasLayerD3D9::Initialize(const Data& aData)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
|
NS_ASSERTION(mDrawTarget == nullptr, "BasicCanvasLayer::Initialize called twice!");
|
||||||
|
|
||||||
if (aData.mDrawTarget) {
|
if (aData.mDrawTarget) {
|
||||||
mDrawTarget = aData.mDrawTarget;
|
mDrawTarget = aData.mDrawTarget;
|
||||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
|
||||||
mNeedsYFlip = false;
|
mNeedsYFlip = false;
|
||||||
mDataIsPremultiplied = true;
|
mDataIsPremultiplied = true;
|
||||||
} else if (aData.mGLContext) {
|
} else if (aData.mGLContext) {
|
||||||
|
@ -55,7 +54,7 @@ CanvasLayerD3D9::Initialize(const Data& aData)
|
||||||
mDataIsPremultiplied = aData.mIsGLAlphaPremult;
|
mDataIsPremultiplied = aData.mIsGLAlphaPremult;
|
||||||
mNeedsYFlip = true;
|
mNeedsYFlip = true;
|
||||||
} else {
|
} else {
|
||||||
NS_ERROR("CanvasLayer created without mSurface, mGLContext or mDrawTarget?");
|
NS_ERROR("CanvasLayer created without mGLContext or mDrawTarget?");
|
||||||
}
|
}
|
||||||
|
|
||||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||||
|
@ -79,87 +78,37 @@ CanvasLayerD3D9::UpdateSurface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<SourceSurface> surface;
|
||||||
|
|
||||||
if (mGLContext) {
|
if (mGLContext) {
|
||||||
SharedSurface* surf = mGLContext->RequestFrame();
|
SharedSurface* surf = mGLContext->RequestFrame();
|
||||||
if (!surf)
|
if (!surf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf);
|
SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf);
|
||||||
|
surface = shareSurf->GetData();
|
||||||
// WebGL reads entire surface.
|
|
||||||
LockTextureRectD3D9 textureLock(mTexture);
|
|
||||||
if (!textureLock.HasLock()) {
|
|
||||||
NS_WARNING("Failed to lock CanvasLayer texture.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3DLOCKED_RECT rect = textureLock.GetLockRect();
|
|
||||||
|
|
||||||
DataSourceSurface* frameData = shareSurf->GetData();
|
|
||||||
// Scope for DrawTarget, so it's destroyed early.
|
|
||||||
{
|
|
||||||
RefPtr<DrawTarget> rectDt = Factory::CreateDrawTargetForData(BackendType::CAIRO,
|
|
||||||
(uint8_t*)rect.pBits,
|
|
||||||
frameData->GetSize(),
|
|
||||||
rect.Pitch,
|
|
||||||
SurfaceFormat::B8G8R8A8);
|
|
||||||
|
|
||||||
Rect drawRect(0, 0, frameData->GetSize().width, frameData->GetSize().height);
|
|
||||||
rectDt->DrawSurface(frameData, drawRect, drawRect,
|
|
||||||
DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE));
|
|
||||||
rectDt->Flush();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
RECT r;
|
surface = mDrawTarget->Snapshot();
|
||||||
r.left = mBounds.x;
|
|
||||||
r.top = mBounds.y;
|
|
||||||
r.right = mBounds.XMost();
|
|
||||||
r.bottom = mBounds.YMost();
|
|
||||||
|
|
||||||
LockTextureRectD3D9 textureLock(mTexture);
|
|
||||||
if (!textureLock.HasLock()) {
|
|
||||||
NS_WARNING("Failed to lock CanvasLayer texture.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3DLOCKED_RECT lockedRect = textureLock.GetLockRect();
|
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> sourceSurface;
|
|
||||||
|
|
||||||
if (mSurface->GetType() == gfxSurfaceType::Win32) {
|
|
||||||
sourceSurface = mSurface->GetAsImageSurface();
|
|
||||||
} else if (mSurface->GetType() == gfxSurfaceType::Image) {
|
|
||||||
sourceSurface = static_cast<gfxImageSurface*>(mSurface.get());
|
|
||||||
if (sourceSurface->Format() != gfxImageFormat::ARGB32 &&
|
|
||||||
sourceSurface->Format() != gfxImageFormat::RGB24)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sourceSurface = new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
|
|
||||||
gfxImageFormat::ARGB32);
|
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(sourceSurface);
|
|
||||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
||||||
ctx->SetSource(mSurface);
|
|
||||||
ctx->Paint();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *startBits = sourceSurface->Data();
|
|
||||||
uint32_t sourceStride = sourceSurface->Stride();
|
|
||||||
|
|
||||||
if (sourceSurface->Format() != gfxImageFormat::ARGB32) {
|
|
||||||
mHasAlpha = false;
|
|
||||||
} else {
|
|
||||||
mHasAlpha = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < mBounds.height; y++) {
|
|
||||||
memcpy((uint8_t*)lockedRect.pBits + lockedRect.Pitch * y,
|
|
||||||
startBits + sourceStride * y,
|
|
||||||
mBounds.width * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WebGL reads entire surface.
|
||||||
|
LockTextureRectD3D9 textureLock(mTexture);
|
||||||
|
if (!textureLock.HasLock()) {
|
||||||
|
NS_WARNING("Failed to lock CanvasLayer texture.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DLOCKED_RECT rect = textureLock.GetLockRect();
|
||||||
|
RefPtr<DrawTarget> rectDt = Factory::CreateDrawTargetForData(BackendType::CAIRO,
|
||||||
|
(uint8_t*)rect.pBits,
|
||||||
|
surface->GetSize(),
|
||||||
|
rect.Pitch,
|
||||||
|
SurfaceFormat::B8G8R8A8);
|
||||||
|
|
||||||
|
Rect drawRect(0, 0, surface->GetSize().width, surface->GetSize().height);
|
||||||
|
rectDt->DrawSurface(surface, drawRect, drawRect,
|
||||||
|
DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE));
|
||||||
|
rectDt->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer*
|
Layer*
|
||||||
|
|
|
@ -39,7 +39,6 @@ protected:
|
||||||
|
|
||||||
void UpdateSurface();
|
void UpdateSurface();
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> mSurface;
|
|
||||||
nsRefPtr<GLContext> mGLContext;
|
nsRefPtr<GLContext> mGLContext;
|
||||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
def table_generator(f):
|
||||||
|
return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
|
||||||
|
|
||||||
|
with open("PremultiplyTables.h", "w") as f:
|
||||||
|
f.write("const uint8_t PremultiplyTable[256*256] = {\n");
|
||||||
|
f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
|
||||||
|
f.write("};\n");
|
||||||
|
f.write("const uint8_t UnpremultiplyTable[256*256] = {\n");
|
||||||
|
f.write(table_generator(lambda i: (i % 256) * 255 / ((i / 256) if (i / 256) > 0 else 255) % 256) + "\n")
|
||||||
|
f.write("};\n");
|
|
@ -1705,6 +1705,12 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
|
||||||
// scroll offset updates from APZ until we acknowledge the update it sent.
|
// scroll offset updates from APZ until we acknowledge the update it sent.
|
||||||
// This prevents APZ updates from clobbering scroll updates from other
|
// This prevents APZ updates from clobbering scroll updates from other
|
||||||
// more "legitimate" sources like content scripts.
|
// more "legitimate" sources like content scripts.
|
||||||
|
// Furthermore, any inflight paint requests we have already dispatched are
|
||||||
|
// going to be ignored by layout, and so mLastDispatchedPaintMetrics
|
||||||
|
// becomes incorrect for the purposes of calculating the LD transform. To
|
||||||
|
// correct this we need to update mLastDispatchedPaintMetrics to be the
|
||||||
|
// last thing we know was painted by Gecko.
|
||||||
|
mLastDispatchedPaintMetrics = aLayerMetrics;
|
||||||
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||||
if (controller) {
|
if (controller) {
|
||||||
controller->AcknowledgeScrollUpdate(aLayerMetrics.mScrollId,
|
controller->AcknowledgeScrollUpdate(aLayerMetrics.mScrollId,
|
||||||
|
|
|
@ -60,13 +60,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
'd3d9/ContainerLayerD3D9.cpp',
|
'd3d9/ContainerLayerD3D9.cpp',
|
||||||
'd3d9/ImageLayerD3D9.cpp',
|
'd3d9/ImageLayerD3D9.cpp',
|
||||||
'd3d9/LayerManagerD3D9.cpp',
|
'd3d9/LayerManagerD3D9.cpp',
|
||||||
'd3d9/Nv3DVUtils.cpp',
|
|
||||||
'd3d9/TextureD3D9.cpp',
|
'd3d9/TextureD3D9.cpp',
|
||||||
'd3d9/ThebesLayerD3D9.cpp',
|
'd3d9/ThebesLayerD3D9.cpp',
|
||||||
]
|
]
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'd3d9/CompositorD3D9.cpp',
|
'd3d9/CompositorD3D9.cpp',
|
||||||
'd3d9/DeviceManagerD3D9.cpp',
|
'd3d9/DeviceManagerD3D9.cpp',
|
||||||
|
'd3d9/Nv3DVUtils.cpp',
|
||||||
]
|
]
|
||||||
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
|
@ -261,6 +261,7 @@ UNIFIED_SOURCES += [
|
||||||
'LayerScope.cpp',
|
'LayerScope.cpp',
|
||||||
'LayersLogging.cpp',
|
'LayersLogging.cpp',
|
||||||
'LayerSorter.cpp',
|
'LayerSorter.cpp',
|
||||||
|
'LayerUtils.cpp',
|
||||||
'opengl/CompositingRenderTargetOGL.cpp',
|
'opengl/CompositingRenderTargetOGL.cpp',
|
||||||
'opengl/CompositorOGL.cpp',
|
'opengl/CompositorOGL.cpp',
|
||||||
'opengl/OGLShaderProgram.cpp',
|
'opengl/OGLShaderProgram.cpp',
|
||||||
|
@ -324,3 +325,7 @@ if CONFIG['MOZ_DEBUG']:
|
||||||
|
|
||||||
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
||||||
DEFINES['MOZ_ENABLE_D3D10_LAYER'] = True
|
DEFINES['MOZ_ENABLE_D3D10_LAYER'] = True
|
||||||
|
|
||||||
|
GENERATED_FILES = [
|
||||||
|
'PremultiplyTables.h',
|
||||||
|
]
|
||||||
|
|
|
@ -136,7 +136,7 @@ NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4, nullptr));
|
JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4));
|
||||||
if (!destArray) {
|
if (!destArray) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,5 +41,5 @@ gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PremultiplyTables.h: $(srcdir)/genTables.py
|
DeprecatedPremultiplyTables.h: $(srcdir)/genTables.py
|
||||||
$(PYTHON) $(srcdir)/genTables.py
|
$(PYTHON) $(srcdir)/genTables.py
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
def table_generator(f):
|
def table_generator(f):
|
||||||
return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
|
return ",\n".join([", ".join(["0x%2.2x" % h for h in [f(i) for i in range(r,r+16)]]) for r in range(0, 65536, 16)])
|
||||||
|
|
||||||
with open("PremultiplyTables.h", "w") as f:
|
with open("DeprecatedPremultiplyTables.h", "w") as f:
|
||||||
f.write("const uint8_t gfxUtils::sPremultiplyTable[256*256] = {\n");
|
f.write("const uint8_t gfxUtils::sPremultiplyTable[256*256] = {\n");
|
||||||
f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
|
f.write(table_generator(lambda i: ((i / 256) * (i % 256) + 254) / 255) + "\n")
|
||||||
f.write("};\n");
|
f.write("};\n");
|
||||||
|
|
|
@ -22,7 +22,7 @@ using namespace mozilla;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
#include "PremultiplyTables.h"
|
#include "DeprecatedPremultiplyTables.h"
|
||||||
|
|
||||||
static const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
static const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
||||||
return gfxUtils::sPremultiplyTable[a*256+v];
|
return gfxUtils::sPremultiplyTable[a*256+v];
|
||||||
|
|
|
@ -628,7 +628,7 @@ gfxWindowsPlatform::CreatePlatformFontList()
|
||||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||||
// bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd
|
// bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd
|
||||||
// crashers so blacklist them altogether
|
// crashers so blacklist them altogether
|
||||||
if (IsWin7RTMOrLater() && GetDWriteFactory()) {
|
if (IsNotWin7PreRTM() && GetDWriteFactory()) {
|
||||||
pfl = new gfxDWriteFontList();
|
pfl = new gfxDWriteFontList();
|
||||||
if (NS_SUCCEEDED(pfl->InitFontList())) {
|
if (NS_SUCCEEDED(pfl->InitFontList())) {
|
||||||
return pfl;
|
return pfl;
|
||||||
|
|
|
@ -268,7 +268,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
GENERATED_FILES = [
|
GENERATED_FILES = [
|
||||||
'PremultiplyTables.h',
|
'DeprecatedPremultiplyTables.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
ipc/chromium/src/third_party/libevent/epoll_sub.c | 13 +++++++++++++
|
||||||
|
1 file changed, 13 insertions(+)
|
||||||
|
|
||||||
|
--- mozilla-central.orig/ipc/chromium/src/third_party/libevent/epoll_sub.c
|
||||||
|
+++ mozilla-central/ipc/chromium/src/third_party/libevent/epoll_sub.c
|
||||||
|
@@ -29,15 +29,24 @@
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_create(int size)
|
||||||
|
{
|
||||||
|
+#if !defined(__NR_epoll_create) && defined(__NR_epoll_create1)
|
||||||
|
+ if (size <= 0) {
|
||||||
|
+ errno = EINVAL;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ return (syscall(__NR_epoll_create1, 0));
|
||||||
|
+#else
|
||||||
|
return (syscall(__NR_epoll_create, size));
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
|
||||||
|
{
|
||||||
|
@@ -46,7 +55,11 @@ epoll_ctl(int epfd, int op, int fd, stru
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
|
||||||
|
{
|
||||||
|
+#if !defined(__NR_epoll_wait) && defined(__NR_epoll_pwait)
|
||||||
|
+ return (syscall(__NR_epoll_pwait, epfd, events, maxevents, timeout, NULL, 0));
|
||||||
|
+#else
|
||||||
|
return (syscall(__NR_epoll_wait, epfd, events, maxevents, timeout));
|
||||||
|
+#endif
|
||||||
|
}
|
|
@ -13,3 +13,5 @@ These files are taken from libevent-2.0.21-stable built on the development envir
|
||||||
3. Apply "add mac-arc4random-buf.patch", which removes some bad OS X compatibility code. This will allow libevent to compile on all supported versions of OS X.
|
3. Apply "add mac-arc4random-buf.patch", which removes some bad OS X compatibility code. This will allow libevent to compile on all supported versions of OS X.
|
||||||
|
|
||||||
4. Apply "openbsd-no-arc4random_addrandom.patch", which fixes the build on OpenBSD (which doesnt provide arc4random_addrandom anymore, see #931354)
|
4. Apply "openbsd-no-arc4random_addrandom.patch", which fixes the build on OpenBSD (which doesnt provide arc4random_addrandom anymore, see #931354)
|
||||||
|
|
||||||
|
5. Apply "libevent-use-non-deprecated-syscalls.patch", which fixes the build on AArch64 architecture (which does not provide deprecated syscalls)
|
||||||
|
|
|
@ -31,11 +31,20 @@
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
epoll_create(int size)
|
epoll_create(int size)
|
||||||
{
|
{
|
||||||
|
#if !defined(__NR_epoll_create) && defined(__NR_epoll_create1)
|
||||||
|
if (size <= 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (syscall(__NR_epoll_create1, 0));
|
||||||
|
#else
|
||||||
return (syscall(__NR_epoll_create, size));
|
return (syscall(__NR_epoll_create, size));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -48,5 +57,9 @@ epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
|
||||||
int
|
int
|
||||||
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
|
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
|
||||||
{
|
{
|
||||||
|
#if !defined(__NR_epoll_wait) && defined(__NR_epoll_pwait)
|
||||||
|
return (syscall(__NR_epoll_pwait, epfd, events, maxevents, timeout, NULL, 0));
|
||||||
|
#else
|
||||||
return (syscall(__NR_epoll_wait, epfd, events, maxevents, timeout));
|
return (syscall(__NR_epoll_wait, epfd, events, maxevents, timeout));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,6 @@ class Float32x4Defn {
|
||||||
|
|
||||||
const JSFunctionSpec js::Float32x4Defn::TypeDescriptorMethods[] = {
|
const JSFunctionSpec js::Float32x4Defn::TypeDescriptorMethods[] = {
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
|
|
||||||
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
|
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
|
||||||
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
|
@ -160,7 +159,6 @@ const JSFunctionSpec js::Float32x4Defn::TypedDatumMethods[] = {
|
||||||
|
|
||||||
const JSFunctionSpec js::Int32x4Defn::TypeDescriptorMethods[] = {
|
const JSFunctionSpec js::Int32x4Defn::TypeDescriptorMethods[] = {
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
|
|
||||||
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
|
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
|
||||||
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
||||||
JS_FS_END,
|
JS_FS_END,
|
||||||
|
|
|
@ -216,7 +216,6 @@ const Class js::ScalarTypeDescr::class_ = {
|
||||||
|
|
||||||
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
|
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
|
|
||||||
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
||||||
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
|
@ -317,7 +316,6 @@ const Class js::ReferenceTypeDescr::class_ = {
|
||||||
|
|
||||||
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
|
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
|
|
||||||
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
||||||
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
|
@ -467,7 +465,6 @@ const JSPropertySpec ArrayMetaTypeDescr::typeObjectProperties[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSFunctionSpec ArrayMetaTypeDescr::typeObjectMethods[] = {
|
const JSFunctionSpec ArrayMetaTypeDescr::typeObjectMethods[] = {
|
||||||
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
|
|
||||||
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
||||||
JS_FN("dimension", UnsizedArrayTypeDescr::dimension, 1, 0),
|
JS_FN("dimension", UnsizedArrayTypeDescr::dimension, 1, 0),
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
|
@ -756,7 +753,6 @@ const JSPropertySpec StructMetaTypeDescr::typeObjectProperties[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSFunctionSpec StructMetaTypeDescr::typeObjectMethods[] = {
|
const JSFunctionSpec StructMetaTypeDescr::typeObjectMethods[] = {
|
||||||
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
|
|
||||||
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
|
||||||
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
|
||||||
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
||||||
|
@ -1250,24 +1246,6 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
|
||||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
JSPROP_READONLY | JSPROP_PERMANENT))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Handle
|
|
||||||
|
|
||||||
RootedObject handle(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
|
|
||||||
if (!module)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!JS_DefineFunctions(cx, handle, TypedHandle::handleStaticMethods))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
RootedValue handleValue(cx, ObjectValue(*handle));
|
|
||||||
if (!JSObject::defineProperty(cx, module, cx->names().Handle,
|
|
||||||
handleValue,
|
|
||||||
nullptr, nullptr,
|
|
||||||
JSPROP_READONLY | JSPROP_PERMANENT))
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything is setup, install module on the global object:
|
// Everything is setup, install module on the global object:
|
||||||
RootedValue moduleValue(cx, ObjectValue(*module));
|
RootedValue moduleValue(cx, ObjectValue(*module));
|
||||||
global->setConstructor(JSProto_TypedObject, moduleValue);
|
global->setConstructor(JSProto_TypedObject, moduleValue);
|
||||||
|
|
|
@ -181,6 +181,12 @@ TypedObjectPointer.prototype.reset = function(inPtr) {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TypedObjectPointer.prototype.bump = function(size) {
|
||||||
|
assert(TO_INT32(this.offset) === this.offset, "current offset not int");
|
||||||
|
assert(TO_INT32(size) === size, "size not int");
|
||||||
|
this.offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
TypedObjectPointer.prototype.kind = function() {
|
TypedObjectPointer.prototype.kind = function() {
|
||||||
return DESCR_KIND(this.descr);
|
return DESCR_KIND(this.descr);
|
||||||
}
|
}
|
||||||
|
@ -312,8 +318,7 @@ TypedObjectPointer.prototype.moveToFieldIndex = function(index) {
|
||||||
// Reifies the value referenced by the pointer, meaning that it
|
// Reifies the value referenced by the pointer, meaning that it
|
||||||
// returns a new object pointing at the value. If the value is
|
// returns a new object pointing at the value. If the value is
|
||||||
// a scalar, it will return a JS number, but otherwise the reified
|
// a scalar, it will return a JS number, but otherwise the reified
|
||||||
// result will be a typed object or handle, depending on the type
|
// result will be a datum of the same class as the ptr's datum.
|
||||||
// of the ptr's datum.
|
|
||||||
TypedObjectPointer.prototype.get = function() {
|
TypedObjectPointer.prototype.get = function() {
|
||||||
assert(ObjectIsAttached(this.datum), "get() called with unattached datum");
|
assert(ObjectIsAttached(this.datum), "get() called with unattached datum");
|
||||||
|
|
||||||
|
@ -328,10 +333,8 @@ TypedObjectPointer.prototype.get = function() {
|
||||||
return this.getX4();
|
return this.getX4();
|
||||||
|
|
||||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
||||||
return NewDerivedTypedDatum(this.descr, this.datum, this.offset);
|
|
||||||
|
|
||||||
case JS_TYPEREPR_STRUCT_KIND:
|
case JS_TYPEREPR_STRUCT_KIND:
|
||||||
return NewDerivedTypedDatum(this.descr, this.datum, this.offset);
|
return this.getDerived();
|
||||||
|
|
||||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
||||||
assert(false, "Unhandled repr kind: " + this.kind());
|
assert(false, "Unhandled repr kind: " + this.kind());
|
||||||
|
@ -341,6 +344,12 @@ TypedObjectPointer.prototype.get = function() {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypedObjectPointer.prototype.getDerived = function() {
|
||||||
|
assert(!TypeDescrIsSimpleType(this.descr),
|
||||||
|
"getDerived() used with simple type");
|
||||||
|
return NewDerivedTypedDatum(this.descr, this.datum, this.offset);
|
||||||
|
}
|
||||||
|
|
||||||
TypedObjectPointer.prototype.getScalar = function() {
|
TypedObjectPointer.prototype.getScalar = function() {
|
||||||
var type = DESCR_TYPE(this.descr);
|
var type = DESCR_TYPE(this.descr);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -726,99 +735,6 @@ function TypedArrayRedimension(newArrayType) {
|
||||||
return NewDerivedTypedDatum(newArrayType, this, 0);
|
return NewDerivedTypedDatum(newArrayType, this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Handles
|
|
||||||
//
|
|
||||||
// Note: these methods are directly invokable by users and so must be
|
|
||||||
// defensive.
|
|
||||||
|
|
||||||
// This is the `handle([obj, [...path]])` method on type objects.
|
|
||||||
// User exposed!
|
|
||||||
//
|
|
||||||
// FIXME bug 929656 -- label algorithms with steps from the spec
|
|
||||||
function HandleCreate(obj, ...path) {
|
|
||||||
if (!IsObject(this) || !ObjectIsTypeDescr(this))
|
|
||||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Type", "handle", "value");
|
|
||||||
|
|
||||||
switch (DESCR_KIND(this)) {
|
|
||||||
case JS_TYPEREPR_SCALAR_KIND:
|
|
||||||
case JS_TYPEREPR_REFERENCE_KIND:
|
|
||||||
case JS_TYPEREPR_X4_KIND:
|
|
||||||
case JS_TYPEREPR_SIZED_ARRAY_KIND:
|
|
||||||
case JS_TYPEREPR_STRUCT_KIND:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
|
|
||||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_TO_UNSIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
var handle = NewTypedHandle(this);
|
|
||||||
|
|
||||||
if (obj !== undefined)
|
|
||||||
HandleMoveInternal(handle, obj, path);
|
|
||||||
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle.move: user exposed!
|
|
||||||
// FIXME bug 929656 -- label algorithms with steps from the spec
|
|
||||||
function HandleMove(handle, obj, ...path) {
|
|
||||||
if (!IsObject(handle) || !ObjectIsTypedHandle(handle))
|
|
||||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Handle", "set", typeof value);
|
|
||||||
|
|
||||||
HandleMoveInternal(handle, obj, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function HandleMoveInternal(handle, obj, path) {
|
|
||||||
assert(IsObject(handle) && ObjectIsTypedHandle(handle),
|
|
||||||
"HandleMoveInternal: not typed handle");
|
|
||||||
|
|
||||||
if (!IsObject(obj) || !ObjectIsTypedDatum(obj))
|
|
||||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Handle", "set", "value");
|
|
||||||
|
|
||||||
var ptr = TypedObjectPointer.fromTypedDatum(obj);
|
|
||||||
for (var i = 0; i < path.length; i++)
|
|
||||||
ptr.moveTo(path[i]);
|
|
||||||
|
|
||||||
// Check that the new destination is equivalent to the handle type.
|
|
||||||
if (DESCR_TYPE_REPR(ptr.descr) !== DATUM_TYPE_REPR(handle))
|
|
||||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE);
|
|
||||||
|
|
||||||
AttachHandle(handle, ptr.datum, ptr.offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle.get: user exposed!
|
|
||||||
// FIXME bug 929656 -- label algorithms with steps from the spec
|
|
||||||
function HandleGet(handle) {
|
|
||||||
if (!IsObject(handle) || !ObjectIsTypedHandle(handle))
|
|
||||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Handle", "set", typeof value);
|
|
||||||
|
|
||||||
if (!ObjectIsAttached(handle))
|
|
||||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
|
|
||||||
|
|
||||||
var ptr = TypedObjectPointer.fromTypedDatum(handle);
|
|
||||||
return ptr.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle.set: user exposed!
|
|
||||||
// FIXME bug 929656 -- label algorithms with steps from the spec
|
|
||||||
function HandleSet(handle, value) {
|
|
||||||
if (!IsObject(handle) || !ObjectIsTypedHandle(handle))
|
|
||||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Handle", "set", typeof value);
|
|
||||||
|
|
||||||
if (!ObjectIsAttached(handle))
|
|
||||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
|
|
||||||
|
|
||||||
var ptr = TypedObjectPointer.fromTypedDatum(handle);
|
|
||||||
ptr.set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle.isHandle: user exposed!
|
|
||||||
// FIXME bug 929656 -- label algorithms with steps from the spec
|
|
||||||
function HandleTest(obj) {
|
|
||||||
return IsObject(obj) && ObjectIsTypedHandle(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// X4
|
// X4
|
||||||
|
|
||||||
|
@ -953,7 +869,6 @@ function TypedObjectArrayTypeFrom(a, b, c) {
|
||||||
// supporting an explicit depth of 1; while for typed input array,
|
// supporting an explicit depth of 1; while for typed input array,
|
||||||
// the expectation is explicit depth.
|
// the expectation is explicit depth.
|
||||||
|
|
||||||
|
|
||||||
if (untypedInput) {
|
if (untypedInput) {
|
||||||
var explicitDepth = (b === 1);
|
var explicitDepth = (b === 1);
|
||||||
if (explicitDepth && IsCallable(c))
|
if (explicitDepth && IsCallable(c))
|
||||||
|
@ -1168,25 +1083,25 @@ function BuildTypedSeqImpl(arrayType, len, depth, func) {
|
||||||
indices[i] = 0;
|
indices[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var handle = callFunction(HandleCreate, grainType);
|
var grainTypeIsSimple = TypeDescrIsSimpleType(grainType);
|
||||||
var offset = 0;
|
var size = DESCR_SIZE(grainType);
|
||||||
|
var outPointer = new TypedObjectPointer(grainType, result, 0);
|
||||||
for (i = 0; i < totalLength; i++) {
|
for (i = 0; i < totalLength; i++) {
|
||||||
// Position handle to point at &result[...indices]
|
// Position out-pointer to point at &result[...indices], if appropriate.
|
||||||
AttachHandle(handle, result, offset);
|
var userOutPointer = (grainTypeIsSimple
|
||||||
|
? undefined
|
||||||
|
: outPointer.getDerived());
|
||||||
|
|
||||||
// Invoke func(...indices, out)
|
// Invoke func(...indices, userOutPointer) and store the result
|
||||||
callFunction(std_Array_push, indices, handle);
|
callFunction(std_Array_push, indices, userOutPointer);
|
||||||
var r = callFunction(std_Function_apply, func, void 0, indices);
|
var r = callFunction(std_Function_apply, func, undefined, indices);
|
||||||
callFunction(std_Array_pop, indices);
|
callFunction(std_Array_pop, indices);
|
||||||
|
if (r !== undefined)
|
||||||
|
outPointer.set(r); // result[...indices] = r;
|
||||||
|
|
||||||
if (r !== undefined) {
|
|
||||||
// result[...indices] = r;
|
|
||||||
AttachHandle(handle, result, offset); // (func might have moved handle)
|
|
||||||
HandleSet(handle, r); // *handle = r
|
|
||||||
}
|
|
||||||
// Increment indices.
|
// Increment indices.
|
||||||
offset += DESCR_SIZE(grainType);
|
|
||||||
IncrementIterationSpace(indices, iterationSpace);
|
IncrementIterationSpace(indices, iterationSpace);
|
||||||
|
outPointer.bump(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1261,35 +1176,32 @@ function MapUntypedSeqImpl(inArray, outputType, maybeFunc) {
|
||||||
// Create a zeroed instance with no data
|
// Create a zeroed instance with no data
|
||||||
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
||||||
|
|
||||||
var outHandle = callFunction(HandleCreate, outGrainType);
|
|
||||||
var outUnitSize = DESCR_SIZE(outGrainType);
|
var outUnitSize = DESCR_SIZE(outGrainType);
|
||||||
|
var outGrainTypeIsSimple = TypeDescrIsSimpleType(outGrainType);
|
||||||
|
var outPointer = new TypedObjectPointer(outGrainType, result, 0);
|
||||||
|
|
||||||
// Core of map computation starts here (comparable to
|
// Core of map computation starts here (comparable to
|
||||||
// DoMapTypedSeqDepth1 and DoMapTypedSeqDepthN below).
|
// DoMapTypedSeqDepth1 and DoMapTypedSeqDepthN below).
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
for (var i = 0; i < outLength; i++) {
|
for (var i = 0; i < outLength; i++) {
|
||||||
// In this loop, since depth is 1, "indices" denotes singleton array [i].
|
// In this loop, since depth is 1, "indices" denotes singleton array [i].
|
||||||
|
|
||||||
// Adjust handle to point at &array[...indices] for result array.
|
|
||||||
AttachHandle(outHandle, result, offset);
|
|
||||||
|
|
||||||
if (i in inArray) { // Check for holes (only needed for untyped case).
|
if (i in inArray) { // Check for holes (only needed for untyped case).
|
||||||
|
// Extract element value.
|
||||||
// Extract element value (no input handles for untyped case).
|
|
||||||
var element = inArray[i];
|
var element = inArray[i];
|
||||||
|
|
||||||
// Invoke: var r = func(element, ...indices, collection, out);
|
// Create out pointer to point at &array[...indices] for result array.
|
||||||
var r = func(element, i, inArray, outHandle);
|
var out = (outGrainTypeIsSimple ? undefined : outPointer.getDerived());
|
||||||
|
|
||||||
if (r !== undefined) {
|
// Invoke: var r = func(element, ...indices, collection, out);
|
||||||
AttachHandle(outHandle, result, offset); // (func could move handle)
|
var r = func(element, i, inArray, out);
|
||||||
HandleSet(outHandle, r); // *handle = r; (i.e. result[i] = r).
|
|
||||||
}
|
if (r !== undefined)
|
||||||
|
outPointer.set(r); // result[i] = r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update offset and (implicitly) increment indices.
|
// Update offset and (implicitly) increment indices.
|
||||||
offset += outUnitSize;
|
outPointer.bump(outUnitSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1320,40 +1232,33 @@ function MapTypedSeqImpl(inArray, depth, outputType, func) {
|
||||||
// Create a zeroed instance with no data
|
// Create a zeroed instance with no data
|
||||||
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
|
||||||
|
|
||||||
var inHandle = callFunction(HandleCreate, inGrainType);
|
var inGrainTypeIsSimple = TypeDescrIsSimpleType(inGrainType);
|
||||||
var outHandle = callFunction(HandleCreate, outGrainType);
|
var outGrainTypeIsSimple = TypeDescrIsSimpleType(outGrainType);
|
||||||
|
|
||||||
|
var inPointer = new TypedObjectPointer(inGrainType, inArray, 0);
|
||||||
|
var outPointer = new TypedObjectPointer(outGrainType, result, 0);
|
||||||
|
|
||||||
var inUnitSize = DESCR_SIZE(inGrainType);
|
var inUnitSize = DESCR_SIZE(inGrainType);
|
||||||
var outUnitSize = DESCR_SIZE(outGrainType);
|
var outUnitSize = DESCR_SIZE(outGrainType);
|
||||||
|
|
||||||
var inGrainTypeIsSimple = TypeDescrIsSimpleType(inGrainType);
|
|
||||||
|
|
||||||
// Bug 956914: add additional variants for depth = 2, 3, etc.
|
// Bug 956914: add additional variants for depth = 2, 3, etc.
|
||||||
|
|
||||||
function DoMapTypedSeqDepth1() {
|
function DoMapTypedSeqDepth1() {
|
||||||
var inOffset = 0;
|
|
||||||
var outOffset = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < totalLength; i++) {
|
for (var i = 0; i < totalLength; i++) {
|
||||||
// In this loop, since depth is 1, "indices" denotes singleton array [i].
|
// In this loop, since depth is 1, "indices" denotes singleton array [i].
|
||||||
|
|
||||||
// Adjust handles to point at &array[...indices] for in and out array.
|
// Prepare input element/handle and out pointer
|
||||||
AttachHandle(inHandle, inArray, inOffset);
|
var element = inPointer.get();
|
||||||
AttachHandle(outHandle, result, outOffset);
|
var out = (outGrainTypeIsSimple ? undefined : outPointer.getDerived());
|
||||||
|
|
||||||
// Extract element value if simple; if not, handle acts as array element.
|
|
||||||
var element = (inGrainTypeIsSimple ? HandleGet(inHandle) : inHandle);
|
|
||||||
|
|
||||||
// Invoke: var r = func(element, ...indices, collection, out);
|
// Invoke: var r = func(element, ...indices, collection, out);
|
||||||
var r = func(element, i, inArray, outHandle);
|
var r = func(element, i, inArray, out);
|
||||||
|
if (r !== undefined)
|
||||||
if (r !== undefined) {
|
outPointer.set(r); // result[i] = r
|
||||||
AttachHandle(outHandle, result, outOffset); // (func could move handle)
|
|
||||||
HandleSet(outHandle, r); // *handle = r; (i.e. result[i] = r).
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update offsets and (implicitly) increment indices.
|
// Update offsets and (implicitly) increment indices.
|
||||||
inOffset += inUnitSize;
|
inPointer.bump(inUnitSize);
|
||||||
outOffset += outUnitSize;
|
outPointer.bump(outUnitSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1362,30 +1267,22 @@ function MapTypedSeqImpl(inArray, depth, outputType, func) {
|
||||||
function DoMapTypedSeqDepthN() {
|
function DoMapTypedSeqDepthN() {
|
||||||
var indices = new Uint32Array(depth);
|
var indices = new Uint32Array(depth);
|
||||||
|
|
||||||
var inOffset = 0;
|
|
||||||
var outOffset = 0;
|
|
||||||
for (var i = 0; i < totalLength; i++) {
|
for (var i = 0; i < totalLength; i++) {
|
||||||
// Adjust handles to point at &array[...indices] for in and out array.
|
// Prepare input element and out pointer
|
||||||
AttachHandle(inHandle, inArray, inOffset);
|
var element = inPointer.get();
|
||||||
AttachHandle(outHandle, result, outOffset);
|
var out = (outGrainTypeIsSimple ? undefined : outPointer.getDerived());
|
||||||
|
|
||||||
// Extract element value if simple; if not, handle acts as array element.
|
|
||||||
var element = (inGrainTypeIsSimple ? HandleGet(inHandle) : inHandle);
|
|
||||||
|
|
||||||
// Invoke: var r = func(element, ...indices, collection, out);
|
// Invoke: var r = func(element, ...indices, collection, out);
|
||||||
var args = [element];
|
var args = [element];
|
||||||
callFunction(std_Function_apply, std_Array_push, args, indices);
|
callFunction(std_Function_apply, std_Array_push, args, indices);
|
||||||
callFunction(std_Array_push, args, inArray, outHandle);
|
callFunction(std_Array_push, args, inArray, out);
|
||||||
var r = callFunction(std_Function_apply, func, void 0, args);
|
var r = callFunction(std_Function_apply, func, void 0, args);
|
||||||
|
if (r !== undefined)
|
||||||
if (r !== undefined) {
|
outPointer.set(r); // result[...indices] = r
|
||||||
AttachHandle(outHandle, result, outOffset); // (func could move handle)
|
|
||||||
HandleSet(outHandle, r); // *handle = r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update offsets and explicitly increment indices.
|
// Update offsets and explicitly increment indices.
|
||||||
inOffset += inUnitSize;
|
inPointer.bump(inUnitSize);
|
||||||
outOffset += outUnitSize;
|
outPointer.bump(outUnitSize);
|
||||||
IncrementIterationSpace(indices, iterationSpace);
|
IncrementIterationSpace(indices, iterationSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1481,14 +1378,15 @@ function FilterTypedSeqImpl(array, func) {
|
||||||
|
|
||||||
var elementType = arrayType.elementType;
|
var elementType = arrayType.elementType;
|
||||||
var flags = new Uint8Array(NUM_BYTES(array.length));
|
var flags = new Uint8Array(NUM_BYTES(array.length));
|
||||||
var handle = callFunction(HandleCreate, elementType);
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
var size = DESCR_SIZE(elementType);
|
||||||
|
var inPointer = new TypedObjectPointer(elementType, array, 0);
|
||||||
for (var i = 0; i < array.length; i++) {
|
for (var i = 0; i < array.length; i++) {
|
||||||
HandleMove(handle, array, i);
|
if (func(inPointer.get(), i, array)) {
|
||||||
if (func(HandleGet(handle), i, array)) {
|
|
||||||
SET_BIT(flags, i);
|
SET_BIT(flags, i);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
inPointer.bump(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultType = (arrayType.variable ? arrayType : arrayType.unsized);
|
var resultType = (arrayType.variable ? arrayType : arrayType.unsized);
|
||||||
|
|
|
@ -826,6 +826,24 @@ darwin*)
|
||||||
linux*)
|
linux*)
|
||||||
HOST_OS_ARCH=Linux
|
HOST_OS_ARCH=Linux
|
||||||
;;
|
;;
|
||||||
|
kfreebsd*-gnu)
|
||||||
|
HOST_OS_ARCH=GNU_kFreeBSD
|
||||||
|
;;
|
||||||
|
gnu*)
|
||||||
|
HOST_OS_ARCH=GNU
|
||||||
|
;;
|
||||||
|
dragonfly*)
|
||||||
|
HOST_OS_ARCH=DragonFly
|
||||||
|
;;
|
||||||
|
freebsd*)
|
||||||
|
HOST_OS_ARCH=FreeBSD
|
||||||
|
;;
|
||||||
|
netbsd*)
|
||||||
|
HOST_OS_ARCH=NetBSD
|
||||||
|
;;
|
||||||
|
openbsd*)
|
||||||
|
HOST_OS_ARCH=OpenBSD
|
||||||
|
;;
|
||||||
solaris*)
|
solaris*)
|
||||||
HOST_OS_ARCH=SunOS
|
HOST_OS_ARCH=SunOS
|
||||||
SOLARIS_SUNPRO_CC=
|
SOLARIS_SUNPRO_CC=
|
||||||
|
|
|
@ -5138,7 +5138,7 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject fieldsProp(cx, JS_NewArrayObject(cx, len, fieldsVec.begin()));
|
RootedObject fieldsProp(cx, JS_NewArrayObject(cx, fieldsVec));
|
||||||
if (!fieldsProp)
|
if (!fieldsProp)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -5946,7 +5946,7 @@ FunctionType::ArgTypesGetter(JSContext* cx, JS::CallArgs args)
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
vec[i] = JS::ObjectValue(*fninfo->mArgTypes[i]);
|
vec[i] = JS::ObjectValue(*fninfo->mArgTypes[i]);
|
||||||
|
|
||||||
argTypes = JS_NewArrayObject(cx, len, vec.begin());
|
argTypes = JS_NewArrayObject(cx, vec);
|
||||||
if (!argTypes)
|
if (!argTypes)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ FRAGMENT(Root, handle) {
|
||||||
|
|
||||||
FRAGMENT(Root, HeapSlot) {
|
FRAGMENT(Root, HeapSlot) {
|
||||||
JS::Rooted<jsval> plinth(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "plinth")));
|
JS::Rooted<jsval> plinth(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "plinth")));
|
||||||
JS::Rooted<JSObject *> array(cx, JS_NewArrayObject(cx, 1, plinth.address()));
|
JS::Rooted<JSObject *> array(cx, JS_NewArrayObject(cx, plinth));
|
||||||
|
|
||||||
breakpoint();
|
breakpoint();
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Test that we can trace a unattached handle.
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/licenses/publicdomain/
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!this.hasOwnProperty("TypedObject"))
|
|
||||||
quit();
|
|
||||||
|
|
||||||
var Object = TypedObject.Object;
|
|
||||||
var handle0 = Object.handle();
|
|
||||||
gc();
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче