Better fix for AMD crashing (hopefully

This commit is contained in:
Brad Davis 2018-01-31 10:38:20 -08:00
parent 9893273d33
commit ef699c2a78
2 changed files with 31 additions and 13 deletions

View file

@ -566,19 +566,22 @@ void OffscreenQmlSurface::render() {
glBindTexture(GL_TEXTURE_2D, texture);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
{
// If the most recent texture was unused, we can directly recycle it
if (_latestTextureAndFence.first) {
offscreenTextures.releaseTexture(_latestTextureAndFence);
_latestTextureAndFence = { 0, 0 };
}
_latestTextureAndFence = { texture, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0) };
auto fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
// Fence will be used in another thread / context, so a flush is required
glFlush();
{
Lock lock(_latestTextureAndFenceMutex);
if (_latestTextureAndFence.first) {
offscreenTextures.releaseTexture(_latestTextureAndFence);
_latestTextureAndFence = { 0, 0 };
}
_latestTextureAndFence = { texture, fence};
}
}
_quickWindow->resetOpenGLState();
@ -590,13 +593,21 @@ void OffscreenQmlSurface::render() {
bool OffscreenQmlSurface::fetchTexture(TextureAndFence& textureAndFence) {
textureAndFence = { 0, 0 };
// Lock free early check
if (0 == _latestTextureAndFence.first) {
return false;
}
// Ensure writes to the latest texture are complete before before returning it for reading
textureAndFence = _latestTextureAndFence;
_latestTextureAndFence = { 0, 0 };
{
Lock lock(_latestTextureAndFenceMutex);
// Double check inside the lock
if (0 == _latestTextureAndFence.first) {
return false;
}
textureAndFence = _latestTextureAndFence;
_latestTextureAndFence = { 0, 0 };
}
return true;
}
@ -815,10 +826,13 @@ void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) {
// Release hold on the textures of the old size
if (uvec2() != _size) {
// If the most recent texture was unused, we can directly recycle it
if (_latestTextureAndFence.first) {
offscreenTextures.releaseTexture(_latestTextureAndFence);
_latestTextureAndFence = { 0, 0 };
{
Lock lock(_latestTextureAndFenceMutex);
// If the most recent texture was unused, we can directly recycle it
if (_latestTextureAndFence.first) {
offscreenTextures.releaseTexture(_latestTextureAndFence);
_latestTextureAndFence = { 0, 0 };
}
}
offscreenTextures.releaseSize(_size);
}

View file

@ -167,6 +167,9 @@ public slots:
bool handlePointerEvent(const PointerEvent& event, class QTouchDevice& device, bool release = false);
private:
using Mutex = std::mutex;
using Lock = std::unique_lock<std::mutex>;
QQuickWindow* _quickWindow { nullptr };
QQmlContext* _qmlContext { nullptr };
QQuickItem* _rootItem { nullptr };
@ -188,6 +191,7 @@ private:
#endif
// Texture management
Mutex _latestTextureAndFenceMutex;
TextureAndFence _latestTextureAndFence { 0, 0 };
bool _render { false };