mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-04 06:40:07 +00:00
Fix issue with overlays on macOS w/the new async painting (fix #1931)
Fixed regression introduced in d20436f9570302e20484b51435276dc9bad94009. Now overlays are kept on the screen and the overlapped area is restored just in time when we have to re-paint some widget on that area.
This commit is contained in:
parent
52e2585c2c
commit
9b2889ef66
@ -1,3 +1,4 @@
|
||||
Copyright (C) 2018 Igara Studio S.A.
|
||||
Copyright (c) 2001-2018 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -243,7 +243,6 @@ void Manager::flipDisplay()
|
||||
update_cursor_overlay();
|
||||
|
||||
// Draw overlays.
|
||||
overlays->captureOverlappedAreas();
|
||||
overlays->drawOverlays();
|
||||
|
||||
// Flip dirty region.
|
||||
@ -257,8 +256,6 @@ void Manager::flipDisplay()
|
||||
|
||||
m_dirtyRegion.clear();
|
||||
}
|
||||
|
||||
overlays->restoreOverlappedAreas();
|
||||
}
|
||||
|
||||
bool Manager::generateMessages()
|
||||
@ -1483,6 +1480,10 @@ bool Manager::sendMessageToWidget(Message* msg, Widget* widget)
|
||||
return false;
|
||||
|
||||
PaintMessage* paintMsg = static_cast<PaintMessage*>(msg);
|
||||
|
||||
// Restore overlays in the region that we're going to paint.
|
||||
OverlayManager::instance()->restoreOverlappedAreas(paintMsg->rect());
|
||||
|
||||
os::Surface* surface = m_display->getSurface();
|
||||
surface->saveClip();
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -18,7 +19,8 @@ namespace ui {
|
||||
|
||||
Overlay::Overlay(os::Surface* overlaySurface, const gfx::Point& pos, ZOrder zorder)
|
||||
: m_surface(overlaySurface)
|
||||
, m_overlap(NULL)
|
||||
, m_overlap(nullptr)
|
||||
, m_captured(nullptr)
|
||||
, m_pos(pos)
|
||||
, m_zorder(zorder)
|
||||
{
|
||||
@ -26,6 +28,8 @@ Overlay::Overlay(os::Surface* overlaySurface, const gfx::Point& pos, ZOrder zord
|
||||
|
||||
Overlay::~Overlay()
|
||||
{
|
||||
ASSERT(!m_captured);
|
||||
|
||||
if (m_surface) {
|
||||
Manager* manager = Manager::getDefault();
|
||||
if (manager)
|
||||
@ -54,13 +58,14 @@ gfx::Rect Overlay::bounds() const
|
||||
return gfx::Rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void Overlay::drawOverlay(os::Surface* screen)
|
||||
void Overlay::drawOverlay()
|
||||
{
|
||||
if (!m_surface)
|
||||
if (!m_surface ||
|
||||
!m_captured)
|
||||
return;
|
||||
|
||||
os::SurfaceLock lock(m_surface);
|
||||
screen->drawRgbaSurface(m_surface, m_pos.x, m_pos.y);
|
||||
m_captured->drawRgbaSurface(m_surface, m_pos.x, m_pos.y);
|
||||
|
||||
Manager::getDefault()->dirtyRect(
|
||||
gfx::Rect(m_pos.x, m_pos.y,
|
||||
@ -70,12 +75,16 @@ void Overlay::drawOverlay(os::Surface* screen)
|
||||
|
||||
void Overlay::moveOverlay(const gfx::Point& newPos)
|
||||
{
|
||||
if (m_captured)
|
||||
restoreOverlappedArea(gfx::Rect());
|
||||
|
||||
m_pos = newPos;
|
||||
}
|
||||
|
||||
void Overlay::captureOverlappedArea(os::Surface* screen)
|
||||
{
|
||||
if (!m_surface)
|
||||
if (!m_surface ||
|
||||
m_captured)
|
||||
return;
|
||||
|
||||
if (!m_overlap) {
|
||||
@ -88,24 +97,28 @@ void Overlay::captureOverlappedArea(os::Surface* screen)
|
||||
os::SurfaceLock lock(m_overlap);
|
||||
screen->blitTo(m_overlap, m_pos.x, m_pos.y, 0, 0,
|
||||
m_overlap->width(), m_overlap->height());
|
||||
|
||||
m_captured = screen;
|
||||
}
|
||||
|
||||
void Overlay::restoreOverlappedArea(os::Surface* screen)
|
||||
void Overlay::restoreOverlappedArea(const gfx::Rect& restoreBounds)
|
||||
{
|
||||
if (!m_surface)
|
||||
if (!m_surface ||
|
||||
!m_overlap ||
|
||||
!m_captured)
|
||||
return;
|
||||
|
||||
if (!m_overlap)
|
||||
if (!restoreBounds.isEmpty() &&
|
||||
!restoreBounds.intersects(bounds()))
|
||||
return;
|
||||
|
||||
os::SurfaceLock lock(m_overlap);
|
||||
m_overlap->blitTo(screen, 0, 0, m_pos.x, m_pos.y,
|
||||
m_overlap->blitTo(m_captured, 0, 0, m_pos.x, m_pos.y,
|
||||
m_overlap->width(), m_overlap->height());
|
||||
|
||||
Manager::getDefault()->dirtyRect(
|
||||
gfx::Rect(m_pos.x, m_pos.y,
|
||||
m_overlap->width(),
|
||||
m_overlap->height()));
|
||||
Manager::getDefault()->dirtyRect(bounds());
|
||||
|
||||
m_captured = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -34,9 +35,9 @@ namespace ui {
|
||||
gfx::Rect bounds() const;
|
||||
|
||||
void captureOverlappedArea(os::Surface* screen);
|
||||
void restoreOverlappedArea(os::Surface* screen);
|
||||
void restoreOverlappedArea(const gfx::Rect& restoreBounds);
|
||||
|
||||
void drawOverlay(os::Surface* screen);
|
||||
void drawOverlay();
|
||||
void moveOverlay(const gfx::Point& newPos);
|
||||
|
||||
bool operator<(const Overlay& other) const {
|
||||
@ -46,6 +47,11 @@ namespace ui {
|
||||
private:
|
||||
os::Surface* m_surface;
|
||||
os::Surface* m_overlap;
|
||||
|
||||
// Surface where we captured the overlapped (m_overlap)
|
||||
// region. It's nullptr if the overlay wasn't drawn yet.
|
||||
os::Surface* m_captured;
|
||||
|
||||
gfx::Point m_pos;
|
||||
ZOrder m_zorder;
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015, 2016 David Capello
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -53,46 +54,46 @@ void OverlayManager::addOverlay(Overlay* overlay)
|
||||
|
||||
void OverlayManager::removeOverlay(Overlay* overlay)
|
||||
{
|
||||
if (overlay)
|
||||
overlay->restoreOverlappedArea(gfx::Rect());
|
||||
|
||||
iterator it = std::find(begin(), end(), overlay);
|
||||
ASSERT(it != end());
|
||||
if (it != end())
|
||||
m_overlays.erase(it);
|
||||
}
|
||||
|
||||
void OverlayManager::captureOverlappedAreas()
|
||||
void OverlayManager::restoreOverlappedAreas(const gfx::Rect& restoreBounds)
|
||||
{
|
||||
if (m_overlays.empty())
|
||||
return;
|
||||
|
||||
// TODO can we remove this?
|
||||
Manager* manager = Manager::getDefault();
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
os::Surface* displaySurface = manager->getDisplay()->getSurface();
|
||||
os::SurfaceLock lock(displaySurface);
|
||||
for (Overlay* overlay : *this)
|
||||
overlay->captureOverlappedArea(displaySurface);
|
||||
}
|
||||
|
||||
void OverlayManager::restoreOverlappedAreas()
|
||||
{
|
||||
Manager* manager = Manager::getDefault();
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
os::Surface* displaySurface = manager->getDisplay()->getSurface();
|
||||
os::SurfaceLock lock(displaySurface);
|
||||
for (Overlay* overlay : *this)
|
||||
overlay->restoreOverlappedArea(displaySurface);
|
||||
overlay->restoreOverlappedArea(restoreBounds);
|
||||
}
|
||||
|
||||
void OverlayManager::drawOverlays()
|
||||
{
|
||||
if (m_overlays.empty())
|
||||
return;
|
||||
|
||||
Manager* manager = Manager::getDefault();
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
os::Surface* displaySurface = manager->getDisplay()->getSurface();
|
||||
os::SurfaceLock lock(displaySurface);
|
||||
|
||||
for (Overlay* overlay : *this)
|
||||
overlay->drawOverlay(displaySurface);
|
||||
overlay->captureOverlappedArea(displaySurface);
|
||||
|
||||
for (Overlay* overlay : *this)
|
||||
overlay->drawOverlay();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -8,6 +9,7 @@
|
||||
#define UI_OVERLAY_MANAGER_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "gfx/rect.h"
|
||||
#include "ui/base.h"
|
||||
#include <vector>
|
||||
|
||||
@ -30,9 +32,8 @@ namespace ui {
|
||||
void addOverlay(Overlay* overlay);
|
||||
void removeOverlay(Overlay* overlay);
|
||||
|
||||
void captureOverlappedAreas();
|
||||
void restoreOverlappedAreas();
|
||||
void drawOverlays();
|
||||
void restoreOverlappedAreas(const gfx::Rect& bounds);
|
||||
|
||||
private:
|
||||
static void destroyInstance();
|
||||
|
Loading…
x
Reference in New Issue
Block a user