aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <[email protected]>2014-01-24 16:37:45 +0100
committerSimon Hausmann <[email protected]>2014-01-24 18:27:41 +0100
commit22041acdfe85c9a9b814e11cd86e8ee5a55be82d (patch)
tree1b4d1bfa0ebba9e5d1495b5ca7055dba94642c46 /src
parent6ae57f01bb1495a74b23a81c590672ce788d5400 (diff)
parent2407cd29e628671f7f5144e0d241d4249a3ab612 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/imports/dialogs/qquickmessagedialog.cpp src/imports/dialogs/qquickmessagedialog_p.h src/qml/debugger/qqmlprofilerservice_p.h src/qml/jsruntime/qv4regexpobject.cpp tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro Change-Id: Ic8a43366b44d6970966acbf03b206d0dee00c28d
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp19
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
-rw-r--r--src/qml/compiler/qv4regalloc.cpp16
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h17
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc2
-rw-r--r--src/qml/jsapi/qjsvalue.cpp2
-rw-r--r--src/qml/jsruntime/qv4alloca_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4mm.cpp8
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp93
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h14
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h3
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp11
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h1
-rw-r--r--src/qml/qml/qqmlcompiler.cpp1
-rw-r--r--src/qml/qml/qqmlinstruction_p.h4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp11
-rw-r--r--src/qml/qml/qqmlmetatype_p.h1
-rw-r--r--src/quick/items/qquickflickable.cpp1
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp38
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h9
-rw-r--r--src/quick/items/qquickpincharea.cpp47
-rw-r--r--src/quick/items/qquickpincharea_p.h9
-rw-r--r--src/quick/items/qquicktext.cpp8
-rw-r--r--src/quick/items/qquickwindow.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp197
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h8
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp34
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp18
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp19
32 files changed, 408 insertions, 202 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 6df94e713d..b8b16a4151 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1966,12 +1966,21 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
Assembler::ScratchRegister);
_as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
} else if (t->type == V4IR::UInt32Type) {
- Address tmp = addressForArgument(0);
- _as->storeUInt32((Assembler::RegisterID) t->index, Pointer(tmp));
- _as->load64(tmp, Assembler::ReturnValueRegister);
+ Assembler::RegisterID srcReg = (Assembler::RegisterID) t->index;
+ Assembler::Jump intRange = _as->branch32(Assembler::GreaterThanOrEqual, srcReg, Assembler::TrustedImm32(0));
+ _as->convertUInt32ToDouble(srcReg, Assembler::FPGpr0, Assembler::ReturnValueRegister);
+ _as->moveDoubleTo64(Assembler::FPGpr0, Assembler::ReturnValueRegister);
+ _as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask), Assembler::ScratchRegister);
+ _as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ Assembler::Jump done = _as->jump();
+ intRange.link(_as);
+ _as->zeroExtend32ToPtr(srcReg, Assembler::ReturnValueRegister);
+ quint64 tag = QV4::Value::_Integer_Type;
+ _as->or64(Assembler::TrustedImm64(tag << 32),
+ Assembler::ReturnValueRegister);
+ done.link(_as);
} else {
- _as->zeroExtend32ToPtr((Assembler::RegisterID) t->index,
- Assembler::ReturnValueRegister);
+ _as->zeroExtend32ToPtr((Assembler::RegisterID) t->index, Assembler::ReturnValueRegister);
quint64 tag;
switch (t->type) {
case V4IR::SInt32Type:
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index f5d4e469e5..a146220015 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1481,6 +1481,7 @@ protected:
typedef Assembler::Address Address;
typedef Assembler::Pointer Pointer;
+#if !defined(ARGUMENTS_IN_REGISTERS)
Address addressForArgument(int index) const
{
// StackFrameRegister points to its old value on the stack, and above
@@ -1488,6 +1489,7 @@ protected:
// values before reaching the first argument.
return Address(Assembler::StackFrameRegister, (index + 2) * sizeof(void*));
}
+#endif
Pointer baseAddressForCallArguments()
{
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index f95cd55b04..2f1f64e523 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -860,7 +860,6 @@ private:
if (it->end() < successorStart)
continue;
- bool lifeTimeHole = false;
bool isPhiTarget = false;
Expr *moveFrom = 0;
@@ -906,9 +905,7 @@ private:
predIt->temp().type);
} else {
int spillSlot = _assignedSpillSlots.value(predIt->temp(), -1);
- if (spillSlot == -1)
- lifeTimeHole = true;
- else
+ if (spillSlot != -1)
moveFrom = createTemp(Temp::StackSlot, spillSlot, predIt->temp().type);
}
break;
@@ -916,9 +913,11 @@ private:
}
}
if (!moveFrom) {
-#if defined(QT_NO_DEBUG)
- Q_UNUSED(lifeTimeHole);
-#else
+#if !defined(QT_NO_DEBUG)
+ bool lifeTimeHole = false;
+ if (it->ranges().first().start <= successorStart && it->ranges().last().end >= successorStart)
+ lifeTimeHole = !it->covers(successorStart);
+
Q_ASSERT(!_info->isPhiTarget(it->temp()) || it->isSplitFromInterval() || lifeTimeHole);
if (_info->def(it->temp()) != successorStart && !it->isSplitFromInterval()) {
const int successorEnd = successor->statements.last()->id;
@@ -960,9 +959,6 @@ private:
moveTo = createTemp(Temp::StackSlot, spillSlot, it->temp().type);
} else {
moveTo = createTemp(Temp::PhysicalRegister, platformRegister(*it), it->temp().type);
- const int spillSlot = _assignedSpillSlots.value(it->temp(), -1);
- if (isPhiTarget && spillSlot != -1)
- mapping.add(moveFrom, createTemp(Temp::StackSlot, spillSlot, it->temp().type));
}
// add move to mapping
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index 6d7c0dcb51..c3329dbb89 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -57,6 +57,7 @@
#include <private/qqmlboundsignal_p.h>
// this contains QUnifiedTimer
#include <private/qabstractanimation_p.h>
+#include <private/qv4function_p.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmetaobject.h>
@@ -401,8 +402,20 @@ struct QQmlBindingProfiler {
struct QQmlHandlingSignalProfiler {
QQmlHandlingSignalProfiler(QQmlBoundSignalExpression *expression)
{
- Q_QML_PROFILE(startHandlingSignal(expression->sourceFile(), expression->lineNumber(),
- expression->columnNumber()));
+ if (QQmlProfilerService::enabled) {
+ if (expression->sourceFile().isEmpty()) {
+ QV4::Function *function = expression->function();
+ if (function) {
+ Q_QML_PROFILE(startHandlingSignal(
+ function->sourceFile(), function->compiledFunction->location.line,
+ function->compiledFunction->location.column));
+ }
+ } else {
+ Q_QML_PROFILE(startHandlingSignal(
+ expression->sourceFile(), expression->lineNumber(),
+ expression->columnNumber()));
+ }
+ }
}
~QQmlHandlingSignalProfiler()
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 19cd3b3f02..d3d3174193 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -238,7 +238,7 @@
Usage:
\code
// First, define the singleton type provider function (callback).
- static QJSValue *example_qjsvalue_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
+ static QJSValue example_qjsvalue_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 0734e92b19..c8de31ef78 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -746,7 +746,7 @@ static bool js_equal(const QString &string, QV4::ValueRef value)
if (value->isNumber())
return __qmljs_string_to_number(string) == value->asDouble();
if (value->isBoolean())
- return __qmljs_string_to_number(string) == value->booleanValue();
+ return __qmljs_string_to_number(string) == double(value->booleanValue());
if (value->isObject()) {
Scope scope(value->objectValue()->engine());
ScopedValue p(scope, __qmljs_to_primitive(value, PREFERREDTYPE_HINT));
diff --git a/src/qml/jsruntime/qv4alloca_p.h b/src/qml/jsruntime/qv4alloca_p.h
index f507d174e1..e51c6dff00 100644
--- a/src/qml/jsruntime/qv4alloca_p.h
+++ b/src/qml/jsruntime/qv4alloca_p.h
@@ -50,7 +50,9 @@
# define alloca _alloca
# endif
#else
+#if !defined(__FreeBSD__) && !defined(__DragonFly__)
# include <alloca.h>
#endif
+#endif
#endif
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 995c711a02..299d11a4a1 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -77,6 +77,9 @@
#if USE(PTHREADS)
# include <pthread.h>
# include <sys/resource.h>
+#if HAVE(PTHREAD_NP_H)
+# include <pthread_np.h>
+#endif
#endif
QT_BEGIN_NAMESPACE
@@ -109,7 +112,11 @@ quintptr getStackLimit()
# else
void* stackBottom = 0;
pthread_attr_t attr;
+#if HAVE(PTHREAD_NP_H) && OS(FREEBSD)
+ if (pthread_attr_get_np(pthread_self(), &attr) == 0) {
+#else
if (pthread_getattr_np(pthread_self(), &attr) == 0) {
+#endif
size_t stackSize = 0;
pthread_attr_getstack(&attr, &stackBottom, &stackSize);
pthread_attr_destroy(&attr);
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index 0af0fea49a..0ba0b18cda 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -67,6 +67,10 @@
#include <sys/storage.h> // __tls()
#endif
+#if USE(PTHREADS) && HAVE(PTHREAD_NP_H)
+#include <pthread_np.h>
+#endif
+
QT_BEGIN_NAMESPACE
using namespace QV4;
@@ -234,7 +238,11 @@ MemoryManager::MemoryManager()
# else
void* stackBottom = 0;
pthread_attr_t attr;
+#if HAVE(PTHREAD_NP_H) && OS(FREEBSD)
+ if (pthread_attr_get_np(pthread_self(), &attr) == 0) {
+#else
if (pthread_getattr_np(pthread_self(), &attr) == 0) {
+#endif
size_t stackSize = 0;
pthread_attr_getstack(&attr, &stackBottom, &stackSize);
pthread_attr_destroy(&attr);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index aafecb5ad8..95b6569196 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -237,6 +237,15 @@ RegExpCtor::RegExpCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("RegExp"))
{
setVTable(staticVTable());
+ clearLastMatch();
+}
+
+void RegExpCtor::clearLastMatch()
+{
+ lastMatch = Primitive::nullValue();
+ lastInput = engine()->newIdentifier(QString());
+ lastMatchStart = 0;
+ lastMatchEnd = 0;
}
ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
@@ -299,6 +308,14 @@ ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
return construct(that, callData);
}
+void RegExpCtor::markObjects(Managed *that, ExecutionEngine *e)
+{
+ RegExpCtor *This = static_cast<RegExpCtor*>(that);
+ This->lastMatch.mark(e);
+ This->lastInput.mark(e);
+ FunctionObject::markObjects(that, e);
+}
+
void RegExpPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
{
Scope scope(engine);
@@ -306,6 +323,28 @@ void RegExpPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
ctor->defineReadonlyProperty(engine->id_prototype, (o = this));
ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(2));
+
+ // Properties deprecated in the spec but required by "the web" :(
+ ctor->defineAccessorProperty(QStringLiteral("lastMatch"), method_get_lastMatch_n<0>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$&"), method_get_lastMatch_n<0>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$1"), method_get_lastMatch_n<1>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$2"), method_get_lastMatch_n<2>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$3"), method_get_lastMatch_n<3>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$4"), method_get_lastMatch_n<4>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$5"), method_get_lastMatch_n<5>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$6"), method_get_lastMatch_n<6>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$7"), method_get_lastMatch_n<7>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$8"), method_get_lastMatch_n<8>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$9"), method_get_lastMatch_n<9>, 0);
+ ctor->defineAccessorProperty(QStringLiteral("lastParen"), method_get_lastParen, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$+"), method_get_lastParen, 0);
+ ctor->defineAccessorProperty(QStringLiteral("input"), method_get_input, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$_"), method_get_input, 0);
+ ctor->defineAccessorProperty(QStringLiteral("leftContext"), method_get_leftContext, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$`"), method_get_leftContext, 0);
+ ctor->defineAccessorProperty(QStringLiteral("rightContext"), method_get_rightContext, 0);
+ ctor->defineAccessorProperty(QStringLiteral("$'"), method_get_rightContext, 0);
+
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(QStringLiteral("exec"), method_exec, 1);
defineDefaultProperty(QStringLiteral("test"), method_test, 1);
@@ -333,7 +372,11 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
}
uint* matchOffsets = (uint*)alloca(r->value->captureCount() * 2 * sizeof(uint));
- int result = r->value->match(s, offset, matchOffsets);
+ const int result = r->value->match(s, offset, matchOffsets);
+
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
+ regExpCtor->clearLastMatch();
+
if (result == -1) {
r->lastIndexProperty(ctx)->value = Primitive::fromInt32(0);
return Encode::null();
@@ -351,10 +394,14 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
array->arrayData->put(i, v);
}
array->setArrayLengthUnchecked(len);
-
array->memberData[Index_ArrayIndex].value = Primitive::fromInt32(result);
array->memberData[Index_ArrayInput].value = arg.asReturnedValue();
+ regExpCtor->lastMatch = array;
+ regExpCtor->lastInput = arg->stringValue();
+ regExpCtor->lastMatchStart = matchOffsets[0];
+ regExpCtor->lastMatchEnd = matchOffsets[1];
+
if (r->global)
r->lastIndexProperty(ctx)->value = Primitive::fromInt32(matchOffsets[1]);
@@ -395,4 +442,46 @@ ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
return Encode::undefined();
}
+template <int index>
+ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
+{
+ Scope scope(ctx);
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastMatch);
+ ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
+ if (result->isUndefined())
+ return ctx->engine->newString(QString())->asReturnedValue();
+ return result.asReturnedValue();
+}
+
+ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
+{
+ Scope scope(ctx);
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastMatch);
+ ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
+ if (result->isUndefined())
+ return ctx->engine->newString(QString())->asReturnedValue();
+ return result.asReturnedValue();
+}
+
+ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx)
+{
+ return static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastInput.asReturnedValue();
+}
+
+ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
+ QString lastInput = regExpCtor->lastInput->toQString();
+ return ctx->engine->newString(lastInput.left(regExpCtor->lastMatchStart))->asReturnedValue();
+}
+
+ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->engine->regExpCtor);
+ QString lastInput = regExpCtor->lastInput->toQString();
+ return ctx->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd))->asReturnedValue();
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index d306efb218..a4cb4b9fb5 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -107,8 +107,15 @@ struct RegExpCtor: FunctionObject
V4_OBJECT
RegExpCtor(ExecutionContext *scope);
+ SafeValue lastMatch;
+ SafeString lastInput;
+ int lastMatchStart;
+ int lastMatchEnd;
+ void clearLastMatch();
+
static ReturnedValue construct(Managed *m, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
+ static void markObjects(Managed *that, ExecutionEngine *e);
};
struct RegExpPrototype: RegExpObject
@@ -120,6 +127,13 @@ struct RegExpPrototype: RegExpObject
static ReturnedValue method_test(CallContext *ctx);
static ReturnedValue method_toString(CallContext *ctx);
static ReturnedValue method_compile(CallContext *ctx);
+
+ template <int index>
+ static ReturnedValue method_get_lastMatch_n(CallContext *ctx);
+ static ReturnedValue method_get_lastParen(CallContext *ctx);
+ static ReturnedValue method_get_input(CallContext *ctx);
+ static ReturnedValue method_get_leftContext(CallContext *ctx);
+ static ReturnedValue method_get_rightContext(CallContext *ctx);
};
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 21f45745cb..2c71a36a3d 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -65,6 +65,9 @@ struct Scope {
explicit Scope(ExecutionEngine *e)
: engine(e)
+#ifndef QT_NO_DEBUG
+ , size(0)
+#endif
{
mark = engine->jsStackTop;
}
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 68160edf5e..bc56fe1f2d 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -136,6 +136,17 @@ QString QQmlBoundSignalExpression::expression() const
}
}
+QV4::Function *QQmlBoundSignalExpression::function() const
+{
+ if (m_expressionFunctionValid) {
+ Q_ASSERT (context() && engine());
+ QV4::Scope scope(QQmlEnginePrivate::get(engine())->v4engine());
+ QV4::Scoped<QV4::FunctionObject> v(scope, m_v8function.value());
+ return v ? v->function : 0;
+ }
+ return 0;
+}
+
// Parts of this function mirror code in QQmlExpressionPrivate::value() and v8value().
// Changes made here may need to be made there and vice versa.
void QQmlBoundSignalExpression::evaluate(void **a)
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index feb79d5484..fe0dbd380e 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -90,6 +90,7 @@ public:
quint16 lineNumber() const { return m_line; }
quint16 columnNumber() const { return m_column; }
QString expression() const;
+ QV4::Function *function() const;
QObject *target() const { return m_target; }
QQmlEngine *engine() const { return context() ? context()->engine : 0; }
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index cd0dea975b..e36f3fd967 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -1681,6 +1681,7 @@ static AST::FunctionDeclaration *convertSignalHandlerExpressionToFunctionDeclara
AST::FunctionBody *body = new (pool) AST::FunctionBody(elements);
AST::FunctionDeclaration *functionDeclaration = new (pool) AST::FunctionDeclaration(jsEngine->newStringRef(signalName), paramList, body);
+ functionDeclaration->functionToken = statement->firstSourceLocation();
return functionDeclaration;
}
diff --git a/src/qml/qml/qqmlinstruction_p.h b/src/qml/qml/qqmlinstruction_p.h
index aeda9832f3..d76c9f9f64 100644
--- a/src/qml/qml/qqmlinstruction_p.h
+++ b/src/qml/qml/qqmlinstruction_p.h
@@ -151,8 +151,10 @@ QT_BEGIN_NAMESPACE
#ifdef QML_THREADED_VME_INTERPRETER
# define QML_INSTR_HEADER void *code;
+# define QML_INSTR_HEADER_INIT this->code = 0;
#else
# define QML_INSTR_HEADER quint8 instructionType;
+# define QML_INSTR_HEADER_INIT this->instructionType = 0;
#endif
#define QML_INSTR_ENUM(I, FMT) I,
@@ -547,6 +549,8 @@ FOR_EACH_QML_INSTR(QML_INSTR_META_TEMPLATE);
template<int Instr>
class QQmlInstructionData : public QQmlInstructionMeta<Instr>::DataType
{
+public:
+ QQmlInstructionData() : QQmlInstructionMeta<Instr>::DataType() { QML_INSTR_HEADER_INIT }
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 1dd8ce0e3e..90d3ca3308 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1836,6 +1836,17 @@ QList<QQmlType*> QQmlMetaType::qmlTypes()
}
/*!
+ Returns the list of all registered types.
+*/
+QList<QQmlType*> QQmlMetaType::qmlAllTypes()
+{
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ return data->types;
+}
+
+/*!
Returns the list of registered QML singleton types.
*/
QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 6c19da6b15..019e6b8821 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -80,6 +80,7 @@ public:
static QList<QString> qmlTypeNames();
static QList<QQmlType*> qmlTypes();
static QList<QQmlType*> qmlSingletonTypes();
+ static QList<QQmlType*> qmlAllTypes();
static QQmlType *qmlType(const QString &qualifiedName, int, int);
static QQmlType *qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int);
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 7cc37e0556..333c11cb29 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -2309,6 +2309,7 @@ void QQuickFlickable::timelineCompleted()
return;
}
movementEnding();
+ d->updateBeginningEnd();
}
void QQuickFlickable::movementStarting()
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 6b273dcd43..973f6efdcc 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -324,7 +324,6 @@ void QQuickTouchPoint::setSceneY(qreal sceneY)
QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
: QQuickItem(parent),
- _currentWindow(0),
_minimumTouchPoints(0),
_maximumTouchPoints(INT_MAX),
_stealMouse(false)
@@ -334,8 +333,8 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
if (qmlVisualTouchDebugging()) {
setFlag(QQuickItem::ItemHasContents);
}
-#ifdef Q_OS_MAC
- connect(this, &QQuickItem::windowChanged, this, &QQuickMultiPointTouchArea::setTouchEventsEnabledForWindow);
+#ifdef Q_OS_OSX
+ setAcceptHoverEvents(true); // needed to enable touch events on mouse hover.
#endif
}
@@ -548,28 +547,31 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p)
_pressedTouchPoints.append(dtp);
}
-void QQuickMultiPointTouchArea::setTouchEventsEnabledForWindow(QWindow *window)
+#ifdef Q_OS_OSX
+void QQuickMultiPointTouchArea::hoverEnterEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+ setTouchEventsEnabled(true);
+}
+
+void QQuickMultiPointTouchArea::hoverLeaveEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+ setTouchEventsEnabled(false);
+}
+
+void QQuickMultiPointTouchArea::setTouchEventsEnabled(bool enable)
{
-#ifdef Q_OS_MAC
// Resolve function for enabling touch events from the (cocoa) platform plugin.
typedef void (*RegisterTouchWindowFunction)(QWindow *, bool);
RegisterTouchWindowFunction registerTouchWindow = reinterpret_cast<RegisterTouchWindowFunction>(
QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration("registertouchwindow"));
if (!registerTouchWindow)
- return; // Not necessarily an error, Qt migh be using a different platform plugin.
-
- // Disable touch on the old window, enable on the new window.
- if (_currentWindow)
- registerTouchWindow(_currentWindow, false);
- if (window)
- registerTouchWindow(window, true);
- // Save the current window, setTouchEventsEnabledForWindow will be called
- // with a null window on disable.
- _currentWindow = window;
-#else // Q_OS_MAC
- Q_UNUSED(window)
-#endif
+ return; // Not necessarily an error, Qt might be using a different platform plugin.
+
+ registerTouchWindow(window(), enable);
}
+#endif // Q_OS_OSX
void QQuickMultiPointTouchArea::addTouchPrototype(QQuickTouchPoint *prototype)
{
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 2e1f2a98fb..83cc407401 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -250,9 +250,11 @@ protected:
bool shouldFilter(QEvent *event);
void grabGesture();
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-protected Q_SLOTS:
- void setTouchEventsEnabledForWindow(QWindow *window);
+#ifdef Q_OS_OSX
+ void hoverEnterEvent(QHoverEvent *event);
+ void hoverLeaveEvent(QHoverEvent *event);
+ void setTouchEventsEnabled(bool enable);
+#endif
private:
void ungrab();
@@ -261,7 +263,6 @@ private:
QList<QObject*> _releasedTouchPoints;
QList<QObject*> _pressedTouchPoints;
QList<QObject*> _movedTouchPoints;
- QWindow *_currentWindow;
int _minimumTouchPoints;
int _maximumTouchPoints;
bool _stealMouse;
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 419792aaa5..f741a08512 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -248,14 +248,13 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
QQuickPinchArea::QQuickPinchArea(QQuickItem *parent)
: QQuickItem(*(new QQuickPinchAreaPrivate), parent)
- , _currentWindow(0)
{
Q_D(QQuickPinchArea);
d->init();
setAcceptedMouseButtons(Qt::LeftButton);
setFiltersChildMouseEvents(true);
-#ifdef Q_OS_MAC
- connect(this, &QQuickItem::windowChanged, this, &QQuickPinchArea::setTouchEventsEnabledForWindow);
+#ifdef Q_OS_OSX
+ setAcceptHoverEvents(true); // needed to enable touch events on mouse hover.
#endif
}
@@ -537,37 +536,39 @@ void QQuickPinchArea::itemChange(ItemChange change, const ItemChangeData &value)
QQuickItem::itemChange(change, value);
}
-QQuickPinch *QQuickPinchArea::pinch()
+#ifdef Q_OS_OSX
+void QQuickPinchArea::hoverEnterEvent(QHoverEvent *event)
{
- Q_D(QQuickPinchArea);
- if (!d->pinch)
- d->pinch = new QQuickPinch;
- return d->pinch;
+ Q_UNUSED(event);
+ setTouchEventsEnabled(true);
}
-void QQuickPinchArea::setTouchEventsEnabledForWindow(QWindow *window)
+void QQuickPinchArea::hoverLeaveEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+ setTouchEventsEnabled(false);
+}
+
+void QQuickPinchArea::setTouchEventsEnabled(bool enable)
{
-#ifdef Q_OS_MAC
// Resolve function for enabling touch events from the (cocoa) platform plugin.
typedef void (*RegisterTouchWindowFunction)(QWindow *, bool);
RegisterTouchWindowFunction registerTouchWindow = reinterpret_cast<RegisterTouchWindowFunction>(
QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration("registertouchwindow"));
if (!registerTouchWindow)
- return; // Not necessarily an error, Qt migh be using a different platform plugin.
-
- // Disable touch on the old window, enable on the new window.
- if (_currentWindow)
- registerTouchWindow(_currentWindow, false);
- if (window)
- registerTouchWindow(window, true);
- // Save the current window, setTouchEventsEnabledForWindow will be called
- // with a null window on disable.
- _currentWindow = window;
-#else // Q_OS_MAC
- Q_UNUSED(window)
-#endif
+ return; // Not necessarily an error, Qt might be using a different platform plugin.
+
+ registerTouchWindow(window(), enable);
}
+#endif // Q_OS_OSX
+QQuickPinch *QQuickPinchArea::pinch()
+{
+ Q_D(QQuickPinchArea);
+ if (!d->pinch)
+ d->pinch = new QQuickPinch;
+ return d->pinch;
+}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index c991145fc7..81bdbda3a1 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -282,9 +282,11 @@ protected:
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
virtual void itemChange(ItemChange change, const ItemChangeData& value);
-
-private Q_SLOTS:
- void setTouchEventsEnabledForWindow(QWindow *window);
+#ifdef Q_OS_OSX
+ void hoverEnterEvent(QHoverEvent *event);
+ void hoverLeaveEvent(QHoverEvent *event);
+ void setTouchEventsEnabled(bool enable);
+#endif
private:
void updatePinch();
@@ -292,7 +294,6 @@ private:
void handleRelease();
private:
- QWindow *_currentWindow;
Q_DISABLE_COPY(QQuickPinchArea)
Q_DECLARE_PRIVATE(QQuickPinchArea)
};
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index beb2039924..5b5dd0ef03 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -2088,7 +2088,7 @@ QRectF QQuickText::boundingRect() const
Q_D(const QQuickText);
QRectF rect = d->layedOutTextRect;
- rect.moveLeft(QQuickTextUtil::alignedX(rect.width(), width(), d->hAlign));
+ rect.moveLeft(QQuickTextUtil::alignedX(rect.width(), width(), effectiveHAlign()));
rect.moveTop(QQuickTextUtil::alignedY(rect.height(), height(), d->vAlign));
if (d->style != Normal)
@@ -2225,11 +2225,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
const QColor linkColor = QColor::fromRgba(d->linkColor);
if (d->richText) {
- const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), width(), d->hAlign);
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), width(), effectiveHAlign());
d->ensureDoc();
node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
} else if (d->layedOutTextRect.width() > 0) {
- const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, width(), d->hAlign);
+ const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, width(), effectiveHAlign());
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
@@ -2501,7 +2501,7 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
link = anchorAt(elideLayout, translatedMousePos);
return link;
} else if (richText && extra.isAllocated() && extra->doc) {
- translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), q->width(), hAlign);
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), q->width(), q->effectiveHAlign());
return extra->doc->documentLayout()->anchorAt(translatedMousePos);
}
return QString();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index c57ca5e838..a311971266 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -343,6 +343,8 @@ void QQuickWindowPrivate::syncSceneGraph()
if (clearBeforeRendering)
mode |= QSGRenderer::ClearColorBuffer;
renderer->setClearMode(mode);
+
+ context->endSync();
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 700ec051ff..1a9669f9ab 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -599,11 +599,6 @@ void Element::computeBounds()
boundsOutsideFloatRange = bounds.isOutsideFloatRange();
}
-RenderNodeElement::~RenderNodeElement()
-{
- delete fbo;
-}
-
bool Batch::isMaterialCompatible(Element *e) const
{
// If material has changed between opaque and translucent, it is not compatible
@@ -751,6 +746,7 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_nextRenderOrder(0)
, m_partialRebuild(false)
, m_partialRebuildRoot(0)
+ , m_useDepthBuffer(true)
, m_opaqueBatches(16)
, m_alphaBatches(16)
, m_batchPool(16)
@@ -761,6 +757,8 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_zRange(0)
, m_currentMaterial(0)
, m_currentShader(0)
+ , m_currentClip(0)
+ , m_currentClipType(NoClip)
, m_vao(0)
{
setNodeUpdater(new Updater(this));
@@ -809,6 +807,8 @@ Renderer::Renderer(QSGRenderContext *ctx)
m_vao = new QOpenGLVertexArrayObject(this);
m_vao->create();
}
+
+ m_useDepthBuffer = ctx->openglContext()->format().depthBufferSize() > 0;
}
static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs)
@@ -1005,6 +1005,8 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
snode->data = e;
Q_ASSERT(!m_renderNodeElements.contains(static_cast<QSGRenderNode *>(node)));
m_renderNodeElements.insert(e->renderNode, e);
+ m_useDepthBuffer = false;
+ m_rebuild |= FullRebuild;
}
QSGNODE_TRAVERSE(node)
@@ -1250,7 +1252,7 @@ void Renderer::buildRenderLists(QSGNode *node)
Q_ASSERT(e);
bool opaque = gn->inheritedOpacity() > OPAQUE_LIMIT && !(gn->activeMaterial()->flags() & QSGMaterial::Blending);
- if (opaque)
+ if (opaque && m_useDepthBuffer)
m_opaqueRenderList << e;
else
m_alphaRenderList << e;
@@ -1631,10 +1633,13 @@ void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData,
}
}
- float *vzorder = (float *) *zData;
- float zorder = 1.0f - e->order * m_zRange;
- for (int i=0; i<vCount; ++i)
- vzorder[i] = zorder;
+ if (m_useDepthBuffer) {
+ float *vzorder = (float *) *zData;
+ float zorder = 1.0f - e->order * m_zRange;
+ for (int i=0; i<vCount; ++i)
+ vzorder[i] = zorder;
+ *zData += vCount * sizeof(float);
+ }
int iCount = g->indexCount();
quint16 *indices = (quint16 *) *indexData;
@@ -1658,7 +1663,6 @@ void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData,
}
*vertexData += vCount * vSize;
- *zData += vCount * sizeof(float);
*indexData += iCount * sizeof(quint16);
*iBase += vCount;
*indexCount += iCount;
@@ -1754,8 +1758,9 @@ void Renderer::uploadBatch(Batch *b)
int bufferSize = b->vertexCount * g->sizeOfVertex();
int ibufferSize = 0;
if (b->merged) {
- bufferSize += b->vertexCount * sizeof(float);
ibufferSize = b->indexCount * sizeof(quint16);
+ if (m_useDepthBuffer)
+ bufferSize += b->vertexCount * sizeof(float);
} else {
ibufferSize = unmergedIndexSize;
}
@@ -1777,7 +1782,7 @@ void Renderer::uploadBatch(Batch *b)
#ifdef QSG_SEPARATE_INDEX_BUFFER
char *indexData = b->ibo.data;
#else
- char *indexData = zData + b->vertexCount * sizeof(float);
+ char *indexData = zData + (m_useDepthBuffer ? b->vertexCount * sizeof(float) : 0);
#endif
quint16 iOffset = 0;
@@ -1857,7 +1862,7 @@ void Renderer::uploadBatch(Batch *b)
dump << ") ";
offset += attr.tupleSize * size_of_type(attr.type);
}
- if (b->merged) {
+ if (b->merged && m_useDepthBuffer) {
float zorder = ((float*)(b->vbo.data + b->vertexCount * g->sizeOfVertex()))[i];
dump << " Z:(" << zorder << ")";
}
@@ -1907,10 +1912,10 @@ void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (batch->isOpaque)
glDisable(GL_DEPTH_TEST);
- ClipType type = updateStencilClip(m_currentClip);
+ m_currentClipType = updateStencilClip(m_currentClip);
if (batch->isOpaque) {
glEnable(GL_DEPTH_TEST);
- if (type & StencilClip)
+ if (m_currentClipType & StencilClip)
glDepthMask(true);
}
}
@@ -2025,7 +2030,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
QSGMaterial *material = gn->activeMaterial();
- ShaderManager::Shader *sms = m_shaderManager->prepareMaterial(material);
+ ShaderManager::Shader *sms = m_useDepthBuffer ? m_shaderManager->prepareMaterial(material) : m_shaderManager->prepareMaterialNoRewrite(material);
QSGMaterialShader *program = sms->program;
if (m_currentShader != sms)
@@ -2054,7 +2059,8 @@ void Renderer::renderMergedBatch(const Batch *batch)
glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, g->sizeOfVertex(), (void *) (qintptr) (offset + draw.vertices));
offset += a.tupleSize * size_of_type(a.type);
}
- glVertexAttribPointer(sms->pos_order, 1, GL_FLOAT, false, 0, (void *) (qintptr) (draw.zorders));
+ if (m_useDepthBuffer)
+ glVertexAttribPointer(sms->pos_order, 1, GL_FLOAT, false, 0, (void *) (qintptr) (draw.zorders));
glDrawElements(g->drawingMode(), draw.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (indexBase + draw.indices));
}
@@ -2136,8 +2142,10 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
m_current_determinant = m_current_model_view_matrix.determinant();
m_current_projection_matrix = projectionMatrix();
- m_current_projection_matrix(2, 2) = m_zRange;
- m_current_projection_matrix(2, 3) = 1.0f - e->order * m_zRange;
+ if (m_useDepthBuffer) {
+ m_current_projection_matrix(2, 2) = m_zRange;
+ m_current_projection_matrix(2, 3) = 1.0f - e->order * m_zRange;
+ }
program->updateState(state(dirty), material, m_currentMaterial);
@@ -2187,25 +2195,25 @@ void Renderer::renderBatches()
<< " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches...";
}
- for (QHash<QSGRenderNode *, RenderNodeElement *>::const_iterator it = m_renderNodeElements.constBegin();
- it != m_renderNodeElements.constEnd(); ++it) {
- prepareRenderNode(it.value());
- }
-
QRect r = viewportRect();
glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height());
glClearColor(clearColor().redF(), clearColor().greenF(), clearColor().blueF(), clearColor().alphaF());
+
+ if (m_useDepthBuffer) {
#if defined(QT_OPENGL_ES)
- glClearDepthf(1);
+ glClearDepthf(1);
#else
- glClearDepth(1);
+ glClearDepth(1);
#endif
-
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glDepthMask(true);
+ glDisable(GL_BLEND);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(false);
+ }
glDisable(GL_CULL_FACE);
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glDepthMask(true);
glColorMask(true, true, true, true);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
@@ -2232,7 +2240,8 @@ void Renderer::renderBatches()
}
glEnable(GL_BLEND);
- glDepthMask(false);
+ if (m_useDepthBuffer)
+ glDepthMask(false);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (Q_LIKELY(renderAlpha)) {
@@ -2252,7 +2261,6 @@ void Renderer::renderBatches()
updateStencilClip(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
}
void Renderer::deleteRemovedElements()
@@ -2404,33 +2412,15 @@ void Renderer::render()
m_vao->release();
}
-void Renderer::prepareRenderNode(RenderNodeElement *e)
+void Renderer::renderRenderNode(Batch *batch)
{
- if (e->fbo && e->fbo->size() != deviceRect().size()) {
- delete e->fbo;
- e->fbo = 0;
- }
+ if (Q_UNLIKELY(debug_render))
+ qDebug() << " -" << batch << "rendernode";
- if (!e->fbo)
- e->fbo = new QOpenGLFramebufferObject(deviceRect().size(), QOpenGLFramebufferObject::CombinedDepthStencil);
- e->fbo->bind();
+ Q_ASSERT(batch->first->isRenderNode);
+ RenderNodeElement *e = (RenderNodeElement *) batch->first;
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- QSGRenderNode::RenderState state;
- QMatrix4x4 pm = projectionMatrix();
- state.projectionMatrix = &pm;
- state.scissorEnabled = false;
- state.stencilEnabled = false;
+ setActiveShader(0, 0);
QSGNode *clip = e->renderNode->parent();
e->renderNode->m_clip_list = 0;
@@ -2442,6 +2432,16 @@ void Renderer::prepareRenderNode(RenderNodeElement *e)
clip = clip->parent();
}
+ updateClip(e->renderNode->m_clip_list, batch);
+
+ QSGRenderNode::RenderState state;
+ QMatrix4x4 pm = projectionMatrix();
+ state.projectionMatrix = &pm;
+ state.scissorEnabled = m_currentClipType & ScissorClip;
+ state.stencilEnabled = m_currentClipType & StencilClip;
+ state.scissorRect = m_current_scissor_rect;
+ state.stencilValue = m_current_stencil_value;
+
QSGNode *xform = e->renderNode->parent();
QMatrix4x4 matrix;
while (xform != rootNode()) {
@@ -2463,66 +2463,51 @@ void Renderer::prepareRenderNode(RenderNodeElement *e)
opacity = opacity->parent();
}
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
e->renderNode->render(state);
e->renderNode->m_matrix = 0;
+ e->renderNode->m_clip_list = 0;
- bindable()->bind();
-}
-
-void Renderer::renderRenderNode(Batch *batch)
-{
- updateStencilClip(0);
- m_currentClip = 0;
-
- setActiveShader(0, 0);
-
- if (!m_shaderManager->blitProgram) {
- m_shaderManager->blitProgram = new QOpenGLShaderProgram();
-
- QSGShaderSourceBuilder::initializeProgramFromFiles(
- m_shaderManager->blitProgram,
- QStringLiteral(":/scenegraph/shaders/rendernode.vert"),
- QStringLiteral(":/scenegraph/shaders/rendernode.frag"));
- m_shaderManager->blitProgram->bindAttributeLocation("av", 0);
- m_shaderManager->blitProgram->bindAttributeLocation("at", 1);
- m_shaderManager->blitProgram->link();
-
- Q_ASSERT(m_shaderManager->blitProgram->isLinked());
+ QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
+ if (changes & QSGRenderNode::ViewportState) {
+ QRect r = viewportRect();
+ glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height());
}
- RenderNodeElement *e = static_cast<RenderNodeElement *>(batch->first);
- glBindTexture(GL_TEXTURE_2D, e->fbo->texture());
-
- m_shaderManager->blitProgram->bind();
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ if (changes & QSGRenderNode::StencilState) {
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilMask(0xff);
+ glDisable(GL_STENCIL_TEST);
+ }
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
+ if (changes & (QSGRenderNode::StencilState | QSGRenderNode::ScissorState)) {
+ glDisable(GL_SCISSOR_TEST);
+ m_currentClip = 0;
+ m_currentClipType = NoClip;
+ }
- float z = 1.0f - e->order * m_zRange;
+ if (changes & QSGRenderNode::DepthState)
+ glDisable(GL_DEPTH_TEST);
- float av[] = { -1, -1, z,
- 1, -1, z,
- -1, 1, z,
- 1, 1, z };
- float at[] = { 0, 0,
- 1, 0,
- 0, 1,
- 1, 1 };
+ if (changes & QSGRenderNode::ColorState)
+ bindable()->reactivate();
- glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, av);
- glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, at);
+ if (changes & QSGRenderNode::BlendState) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ if (changes & QSGRenderNode::CullState) {
+ glFrontFace(isMirrored() ? GL_CW : GL_CCW);
+ glDisable(GL_CULL_FACE);
+ }
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glBindTexture(GL_TEXTURE_2D, 0);
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 001c3b21ab..0aa84da185 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -194,15 +194,11 @@ struct RenderNodeElement : public Element {
RenderNodeElement(QSGRenderNode *rn)
: Element(0)
, renderNode(rn)
- , fbo(0)
{
isRenderNode = true;
}
- ~RenderNodeElement();
-
QSGRenderNode *renderNode;
- QOpenGLFramebufferObject *fbo;
};
struct BatchRootInfo {
@@ -436,7 +432,6 @@ private:
void renderUnmergedBatch(const Batch *batch);
void updateClip(const QSGClipNode *clipList, const Batch *batch);
const QMatrix4x4 &matrixForRoot(Node *node);
- void prepareRenderNode(RenderNodeElement *e);
void renderRenderNode(Batch *batch);
void setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
@@ -460,6 +455,8 @@ private:
bool m_partialRebuild;
QSGNode *m_partialRebuildRoot;
+ bool m_useDepthBuffer;
+
QHash<QSGRenderNode *, RenderNodeElement *> m_renderNodeElements;
QDataBuffer<Batch *> m_opaqueBatches;
QDataBuffer<Batch *> m_alphaBatches;
@@ -483,6 +480,7 @@ private:
QSGMaterialShader *m_currentProgram;
ShaderManager::Shader *m_currentShader;
const QSGClipNode *m_currentClip;
+ ClipType m_currentClipType;
// For minimal OpenGL core profile support
QOpenGLVertexArrayObject *m_vao;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 90803db9fe..829d33a0d7 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -210,10 +210,17 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
static bool dumped = false;
if (!dumped && qEnvironmentVariableIsSet("QSG_INFO")) {
dumped = true;
- qDebug() << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR);
- qDebug() << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER);
- qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
- qDebug() << "GL_EXTENSIONS:\n " << QByteArray((const char *) glGetString(GL_EXTENSIONS)).replace(" ", "\n ").constData();
+ QSurfaceFormat format = renderContext->openglContext()->format();
+ qDebug() << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
+ qDebug() << "Depth Buffer: " << format.depthBufferSize();
+ qDebug() << "Stencil Buffer: " << format.stencilBufferSize();
+ qDebug() << "Samples: " << format.samples();
+ qDebug() << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR);
+ qDebug() << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER);
+ qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
+ QSet<QByteArray> exts = renderContext->openglContext()->extensions();
+ QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e;
+ qDebug() << "GL_EXTENSIONS: " << all.constData();
}
d->mutex.unlock();
@@ -282,8 +289,10 @@ QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc)
QSurfaceFormat QSGContext::defaultSurfaceFormat() const
{
QSurfaceFormat format;
- format.setDepthBufferSize(24);
- format.setStencilBufferSize(8);
+ static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER");
+ format.setDepthBufferSize(useDepth ? 24 : 0);
+ format.setStencilBufferSize(useStencil ? 8 : 0);
if (QQuickWindow::hasDefaultAlphaBuffer())
format.setAlphaBufferSize(8);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
@@ -349,6 +358,12 @@ QSGRenderContext::~QSGRenderContext()
invalidate();
}
+void QSGRenderContext::endSync()
+{
+ qDeleteAll(m_texturesToDelete);
+ m_texturesToDelete.clear();
+}
+
static QBasicMutex qsg_framerender_mutex;
void QSGRenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
@@ -466,6 +481,9 @@ void QSGRenderContext::invalidate()
if (!m_gl)
return;
+ qDeleteAll(m_texturesToDelete);
+ m_texturesToDelete.clear();
+
qDeleteAll(m_textures.values());
m_textures.clear();
@@ -608,10 +626,8 @@ QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, Q
void QSGRenderContext::textureFactoryDestroyed(QObject *o)
{
m_mutex.lock();
- QSGTexture *t = m_textures.take(static_cast<QQuickTextureFactory *>(o));
+ m_texturesToDelete << m_textures.take(static_cast<QQuickTextureFactory *>(o));
m_mutex.unlock();
- if (t)
- t->deleteLater();
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index c562a909c5..c1bf78a018 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -94,6 +94,7 @@ public:
virtual void invalidate();
virtual void renderNextFrame(QSGRenderer *renderer, GLuint fboId);
+ virtual void endSync();
virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo);
QSGDepthStencilBufferManager *depthStencilBufferManager();
@@ -124,6 +125,7 @@ protected:
QMutex m_mutex;
QHash<QQuickTextureFactory *, QSGTexture *> m_textures;
+ QSet<QSGTexture *> m_texturesToDelete;
QSGAtlasTexture::Manager *m_atlasManager;
QSGDepthStencilBufferManager *m_depthStencilManager;
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
index fb989fd6fb..810a503cee 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
@@ -385,7 +385,7 @@ void QSGDefaultRectangleNode::updateGeometry()
int borderTail = 0;
int outerAAHead = 0;
int outerAATail = 0;
- bool hasFill = m_color.rgba() != 0 || !stops.isEmpty();
+ bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
if (hasFill)
indexCount += fillIndexCount;
if (m_antialiasing) {
@@ -609,7 +609,7 @@ void QSGDefaultRectangleNode::updateGeometry()
int borderTail = 0;
int outerAAHead = 0;
int outerAATail = 0;
- bool hasFill = m_color.rgba() != 0 || !stops.isEmpty();
+ bool hasFill = m_color.alpha() > 0 || !stops.isEmpty();
if (hasFill)
indexCount += fillIndexCount;
if (m_antialiasing) {
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 6e0fdc7290..d080c59198 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -48,6 +48,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QSurface>
+#include <QtGui/qpa/qplatformnativeinterface.h>
#include <private/qsgtexture_p.h>
@@ -144,10 +145,21 @@ Atlas::Atlas(const QSize &size)
{
#ifdef QT_OPENGL_ES
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
+ QString *deviceName =
+ static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
+ static bool wrongfullyReportsBgra8888Support = deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0;
+#else
+ static bool wrongfullyReportsBgra8888Support = false;
+#endif
+
const char *ext = (const char *) glGetString(GL_EXTENSIONS);
- if (strstr(ext, "GL_EXT_bgra")
- || strstr(ext, "GL_EXT_texture_format_BGRA8888")
- || strstr(ext, "GL_IMG_texture_format_BGRA8888")) {
+ if (!wrongfullyReportsBgra8888Support
+ && (strstr(ext, "GL_EXT_bgra")
+ || strstr(ext, "GL_EXT_texture_format_BGRA8888")
+ || strstr(ext, "GL_IMG_texture_format_BGRA8888"))) {
m_internalFormat = m_externalFormat = GL_BGRA;
#ifdef Q_OS_IOS
} else if (strstr(ext, "GL_APPLE_texture_format_BGRA8888")) {
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index d84ccb7a1f..ae1bec3f42 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -47,8 +47,10 @@
#include <qthread.h>
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlglobal_p.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qpa/qplatformnativeinterface.h>
-#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__)
#define CAN_BACKTRACE_EXECINFO
#endif
@@ -679,14 +681,25 @@ void QSGPlainTexture::bind()
GLenum externalFormat = GL_RGBA;
GLenum internalFormat = GL_RGBA;
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
+ QString *deviceName =
+ static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
+ static bool wrongfullyReportsBgra8888Support = deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0;
+#else
+ static bool wrongfullyReportsBgra8888Support = false;
+#endif
+
QOpenGLContext *context = QOpenGLContext::currentContext();
if (context->hasExtension(QByteArrayLiteral("GL_EXT_bgra"))) {
externalFormat = GL_BGRA;
#ifdef QT_OPENGL_ES
internalFormat = GL_BGRA;
#endif
- } else if (context->hasExtension(QByteArrayLiteral("GL_EXT_texture_format_BGRA8888"))
- || context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888"))) {
+ } else if (!wrongfullyReportsBgra8888Support
+ && (context->hasExtension(QByteArrayLiteral("GL_EXT_texture_format_BGRA8888"))
+ || context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888")))) {
externalFormat = GL_BGRA;
internalFormat = GL_BGRA;
#ifdef Q_OS_IOS