mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 09:22:18 -07:00
Some attempts to refresh macOS compositor
Took 2 minutes
This commit is contained in:
parent
1c85a4aad8
commit
37bb1786cd
5 changed files with 58 additions and 2 deletions
|
|
@ -128,7 +128,16 @@ void GameView::resizeRubberBand(const QPointF &cursorPoint, int selectedCount)
|
||||||
|
|
||||||
QPoint cursor = cursorPoint.toPoint();
|
QPoint cursor = cursorPoint.toPoint();
|
||||||
QRect rect = QRect(mapFromScene(selectionOrigin), cursor).normalized();
|
QRect rect = QRect(mapFromScene(selectionOrigin), cursor).normalized();
|
||||||
|
|
||||||
|
// Explicitly repaint the strip the band just vacated. When the band is a
|
||||||
|
// child widget, the viewport does not reliably receive the exposed region
|
||||||
|
// on all platforms (notably macOS), which would leave stale band pixels on
|
||||||
|
// screen until the next unrelated repaint.
|
||||||
|
const QRect previousGeometry = rubberBand->geometry();
|
||||||
rubberBand->setGeometry(rect);
|
rubberBand->setGeometry(rect);
|
||||||
|
if (viewport()) {
|
||||||
|
viewport()->update(previousGeometry.united(rect));
|
||||||
|
}
|
||||||
|
|
||||||
if (!SettingsCache::instance().userInterface().getShowDragSelectionCount()) {
|
if (!SettingsCache::instance().userInterface().getShowDragSelectionCount()) {
|
||||||
dragCountLabel->hide();
|
dragCountLabel->hide();
|
||||||
|
|
@ -171,7 +180,14 @@ void GameView::stopRubberBand()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same rationale as resizeRubberBand. Make sure the area under the band is
|
||||||
|
// repainted, since some platforms skip the exposed-region update of a
|
||||||
|
// hidden child widget.
|
||||||
|
const QRect bandGeometry = rubberBand->geometry();
|
||||||
rubberBand->hide();
|
rubberBand->hide();
|
||||||
|
if (viewport()) {
|
||||||
|
viewport()->update(bandGeometry);
|
||||||
|
}
|
||||||
dragCountLabel->hide();
|
dragCountLabel->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,15 +190,40 @@ void PlayerGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
|
||||||
const QRectF srcRect = computeArtSourceRect(playmatPixmap.size(), playmatParams);
|
const QRectF srcRect = computeArtSourceRect(playmatPixmap.size(), playmatParams);
|
||||||
const QRectF dstRect = coverFitRect(combinedArea, srcRect.size());
|
const QRectF dstRect = coverFitRect(combinedArea, srcRect.size());
|
||||||
|
|
||||||
|
painter->save();
|
||||||
painter->setClipRect(combinedArea);
|
painter->setClipRect(combinedArea);
|
||||||
painter->drawPixmap(dstRect, playmatPixmap, srcRect);
|
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||||
painter->setClipping(false);
|
|
||||||
|
// Render from a down-scaled copy of the art so the full-resolution source
|
||||||
|
// pixmap is never re-sampled at a tiny device size (also much cheaper than
|
||||||
|
// scaling it on every frame).
|
||||||
|
const QPixmap scaledPixmap = scaledPlaymatFor(srcRect, painter->worldTransform().mapRect(dstRect).size());
|
||||||
|
painter->drawPixmap(dstRect, scaledPixmap, QRectF(scaledPixmap.rect()));
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
if (!playmatAttribution.isEmpty()) {
|
if (!playmatAttribution.isEmpty()) {
|
||||||
paintArtAttribution(*painter, combinedArea, playmatAttribution, Qt::AlignRight | Qt::AlignBottom, 0.8);
|
paintArtAttribution(*painter, combinedArea, playmatAttribution, Qt::AlignRight | Qt::AlignBottom, 0.8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap PlayerGraphicsItem::scaledPlaymatFor(const QRectF &srcRect, const QSizeF &deviceDstSize)
|
||||||
|
{
|
||||||
|
// Bucket the render size so the source pixmap is re-scaled at most once per
|
||||||
|
// zoom step instead of once per frame.
|
||||||
|
constexpr int bucketSize = 32;
|
||||||
|
const QSize target = QSize(qMax(1, qRound(deviceDstSize.width() / bucketSize) * bucketSize),
|
||||||
|
qMax(1, qRound(deviceDstSize.height() / bucketSize) * bucketSize))
|
||||||
|
.boundedTo(srcRect.toAlignedRect().size());
|
||||||
|
|
||||||
|
if (scaledPlaymatKey != target) {
|
||||||
|
const QPixmap crop = playmatPixmap.copy(srcRect.toAlignedRect());
|
||||||
|
scaledPlaymatPixmap = crop.scaled(target, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
scaledPlaymatKey = target;
|
||||||
|
}
|
||||||
|
return scaledPlaymatPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerGraphicsItem::processSceneSizeChange(int newPlayerWidth)
|
void PlayerGraphicsItem::processSceneSizeChange(int newPlayerWidth)
|
||||||
{
|
{
|
||||||
// Extend table (and hand, if horizontal) to accommodate the new player width.
|
// Extend table (and hand, if horizontal) to accommodate the new player width.
|
||||||
|
|
@ -372,6 +397,7 @@ void PlayerGraphicsItem::updatePlaymat()
|
||||||
}
|
}
|
||||||
|
|
||||||
playmatParams = params;
|
playmatParams = params;
|
||||||
|
scaledPlaymatKey = QSize(); // the art crop depends on the params, drop any cached scale
|
||||||
|
|
||||||
ExactCard card = CardDatabaseManager::query()->getCard(playmatCard);
|
ExactCard card = CardDatabaseManager::query()->getCard(playmatCard);
|
||||||
if (!card) {
|
if (!card) {
|
||||||
|
|
@ -409,6 +435,7 @@ void PlayerGraphicsItem::clearPlaymat()
|
||||||
if (hasPlaymat) {
|
if (hasPlaymat) {
|
||||||
hasPlaymat = false;
|
hasPlaymat = false;
|
||||||
playmatPixmap = QPixmap();
|
playmatPixmap = QPixmap();
|
||||||
|
scaledPlaymatKey = QSize();
|
||||||
emit playmatChanged(false);
|
emit playmatChanged(false);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,8 @@ private:
|
||||||
bool handVisible = false;
|
bool handVisible = false;
|
||||||
|
|
||||||
QPixmap playmatPixmap;
|
QPixmap playmatPixmap;
|
||||||
|
QPixmap scaledPlaymatPixmap; // down-scaled copy of playmatPixmap for the current render size
|
||||||
|
QSize scaledPlaymatKey; // size bucket scaledPlaymatPixmap was rendered for
|
||||||
PlaymatParams playmatParams;
|
PlaymatParams playmatParams;
|
||||||
QString playmatAttribution;
|
QString playmatAttribution;
|
||||||
bool hasPlaymat = false;
|
bool hasPlaymat = false;
|
||||||
|
|
@ -160,6 +162,9 @@ private slots:
|
||||||
void clearPlaymat();
|
void clearPlaymat();
|
||||||
void updatePlaymat();
|
void updatePlaymat();
|
||||||
void onPlaymatPixmapReady();
|
void onPlaymatPixmapReady();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPixmap scaledPlaymatFor(const QRectF &srcRect, const QSizeF &deviceDstSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COCKATRICE_PLAYER_GRAPHICS_ITEM_H
|
#endif // COCKATRICE_PLAYER_GRAPHICS_ITEM_H
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti
|
||||||
void StackZone::onPlaymatChanged(bool active)
|
void StackZone::onPlaymatChanged(bool active)
|
||||||
{
|
{
|
||||||
playmatActive = active;
|
playmatActive = active;
|
||||||
|
// See TableZone::onPlaymatChanged for the rationale. Translucent overlay
|
||||||
|
// over a dynamic playmat should not be held in the device cache.
|
||||||
|
setCacheMode(active ? QGraphicsItem::NoCache : QGraphicsItem::DeviceCoordinateCache);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,11 @@ void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti
|
||||||
void TableZone::onPlaymatChanged(bool active)
|
void TableZone::onPlaymatChanged(bool active)
|
||||||
{
|
{
|
||||||
playmatActive = active;
|
playmatActive = active;
|
||||||
|
// While a playmat is shown the zone paints a translucent overlay over the
|
||||||
|
// dynamic playmat behind it. Keep it out of the device cache so the cached
|
||||||
|
// pixels are never stale relative to the playmat (and to avoid compositing
|
||||||
|
// artifacts of cached translucent content on some platforms).
|
||||||
|
setCacheMode(active ? QGraphicsItem::NoCache : QGraphicsItem::DeviceCoordinateCache);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue