mirror of
https://github.com/overte-org/overte.git
synced 2025-04-09 15:22:27 +02:00
Merge pull request #15023 from SamGondelman/web
Case 21171: Web entity thread safety and fixes
This commit is contained in:
commit
f1541c3df4
2 changed files with 79 additions and 64 deletions
|
@ -101,21 +101,15 @@ bool WebEntityRenderer::isTransparent() const {
|
|||
}
|
||||
|
||||
bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||
if (_contextPosition != entity->getWorldPosition()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
QSharedPointer<OffscreenQmlSurface> webSurface;
|
||||
withReadLock([&] {
|
||||
webSurface = _webSurface;
|
||||
});
|
||||
if (webSurface && uvec2(getWindowSize(entity)) != toGlm(webSurface->size())) {
|
||||
if (resultWithReadLock<bool>([&] {
|
||||
if (_webSurface && uvec2(getWindowSize(entity)) != toGlm(_webSurface->size())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_contextPosition != entity->getWorldPosition()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(resultWithReadLock<bool>([&] {
|
||||
if (_color != entity->getColor()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -194,7 +188,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
auto newContentType = getContentType(newSourceURL);
|
||||
ContentType currentContentType;
|
||||
withReadLock([&] {
|
||||
urlChanged = _sourceURL != newSourceURL;
|
||||
urlChanged = newSourceURL.isEmpty() || newSourceURL != _tryingToBuildURL;
|
||||
});
|
||||
currentContentType = _contentType;
|
||||
|
||||
|
@ -206,7 +200,6 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
withWriteLock([&] {
|
||||
_inputMode = entity->getInputMode();
|
||||
_dpi = entity->getDPI();
|
||||
|
@ -216,6 +209,8 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
_billboardMode = entity->getBillboardMode();
|
||||
|
||||
if (_contentType == ContentType::NoContent) {
|
||||
_tryingToBuildURL = newSourceURL;
|
||||
_sourceURL = newSourceURL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -226,10 +221,12 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
|
||||
if (_webSurface) {
|
||||
if (_webSurface->getRootItem()) {
|
||||
if (_contentType == ContentType::HtmlContent && urlChanged) {
|
||||
if (_contentType == ContentType::HtmlContent && _sourceURL != newSourceURL) {
|
||||
_webSurface->getRootItem()->setProperty(URL_PROPERTY, newSourceURL);
|
||||
_sourceURL = newSourceURL;
|
||||
} else if (_contentType != ContentType::HtmlContent) {
|
||||
_sourceURL = newSourceURL;
|
||||
}
|
||||
_sourceURL = newSourceURL;
|
||||
|
||||
{
|
||||
auto scriptURL = entity->getScriptURL();
|
||||
|
@ -294,20 +291,21 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
});
|
||||
|
||||
// Try to update the texture
|
||||
{
|
||||
QSharedPointer<OffscreenQmlSurface> webSurface;
|
||||
withReadLock([&] {
|
||||
webSurface = _webSurface;
|
||||
});
|
||||
if (!webSurface) {
|
||||
return;
|
||||
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
|
||||
bool newTextureAvailable = false;
|
||||
if (!resultWithReadLock<bool>([&] {
|
||||
if (!_webSurface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
|
||||
bool newTextureAvailable = webSurface->fetchTexture(newTextureAndFence);
|
||||
if (newTextureAvailable) {
|
||||
_texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second);
|
||||
}
|
||||
newTextureAvailable = _webSurface->fetchTexture(newTextureAndFence);
|
||||
return true;
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newTextureAvailable) {
|
||||
_texture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second);
|
||||
}
|
||||
|
||||
static const glm::vec2 texMin(0.0f), texMax(1.0f), topLeft(-0.5f), bottomRight(0.5f);
|
||||
|
@ -351,6 +349,8 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q
|
|||
_connections.push_back(QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, [entityItemID](const QVariant& message) {
|
||||
emit DependencyManager::get<EntityScriptingInterface>()->webEventReceived(entityItemID, message);
|
||||
}));
|
||||
|
||||
_tryingToBuildURL = newSourceURL;
|
||||
}
|
||||
|
||||
void WebEntityRenderer::destroyWebSurface() {
|
||||
|
@ -383,11 +383,16 @@ glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) con
|
|||
void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) {
|
||||
if (_inputMode == WebInputMode::MOUSE) {
|
||||
handlePointerEvent(event);
|
||||
} else if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->hoverBeginEvent(webEvent, _touchDevice);
|
||||
return;
|
||||
}
|
||||
|
||||
withReadLock([&] {
|
||||
if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->hoverBeginEvent(webEvent, _touchDevice);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) {
|
||||
|
@ -398,34 +403,39 @@ void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) {
|
|||
// QML onReleased is only triggered if a click has happened first. We need to send this "fake" mouse move event to properly trigger an onExited.
|
||||
PointerEvent endMoveEvent(PointerEvent::Move, event.getID());
|
||||
handlePointerEvent(endMoveEvent);
|
||||
} else if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->hoverEndEvent(webEvent, _touchDevice);
|
||||
}
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) {
|
||||
if (_inputMode == WebInputMode::TOUCH) {
|
||||
handlePointerEventAsTouch(event);
|
||||
} else {
|
||||
handlePointerEventAsMouse(event);
|
||||
}
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEventAsTouch(const PointerEvent& event) {
|
||||
if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->handlePointerEvent(webEvent, _touchDevice);
|
||||
}
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) {
|
||||
if (!_webSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
withReadLock([&] {
|
||||
if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->hoverEndEvent(webEvent, _touchDevice);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) {
|
||||
withReadLock([&] {
|
||||
if (!_webSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_inputMode == WebInputMode::TOUCH) {
|
||||
handlePointerEventAsTouch(event);
|
||||
} else {
|
||||
handlePointerEventAsMouse(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEventAsTouch(const PointerEvent& event) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->handlePointerEvent(webEvent, _touchDevice);
|
||||
}
|
||||
|
||||
void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) {
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _dpi);
|
||||
QPointF windowPoint(windowPos.x, windowPos.y);
|
||||
|
||||
|
@ -459,16 +469,20 @@ void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) {
|
|||
}
|
||||
|
||||
void WebEntityRenderer::setProxyWindow(QWindow* proxyWindow) {
|
||||
if (_webSurface) {
|
||||
_webSurface->setProxyWindow(proxyWindow);
|
||||
}
|
||||
withReadLock([&] {
|
||||
if (_webSurface) {
|
||||
_webSurface->setProxyWindow(proxyWindow);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QObject* WebEntityRenderer::getEventHandler() {
|
||||
if (!_webSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
return _webSurface->getEventHandler();
|
||||
return resultWithReadLock<QObject*>([&]() -> QObject* {
|
||||
if (!_webSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
return _webSurface->getEventHandler();
|
||||
});
|
||||
}
|
||||
|
||||
void WebEntityRenderer::emitScriptEvent(const QVariant& message) {
|
||||
|
|
|
@ -82,6 +82,7 @@ private:
|
|||
QSharedPointer<OffscreenQmlSurface> _webSurface { nullptr };
|
||||
bool _cachedWebSurface { false };
|
||||
gpu::TexturePointer _texture;
|
||||
QString _tryingToBuildURL;
|
||||
|
||||
glm::u8vec3 _color;
|
||||
float _alpha { 1.0f };
|
||||
|
|
Loading…
Reference in a new issue