mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-31 15:59:54 +00:00
Image options are used in cache key. Medias with captions has tails.
This commit is contained in:
parent
b1ca0f5ea3
commit
38d20c506e
@ -173,7 +173,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool skipBubbleTail() const override {
|
bool skipBubbleTail() const override {
|
||||||
return isBubbleBottom();
|
return isBubbleBottom() && _caption.isEmpty();
|
||||||
}
|
}
|
||||||
bool isReadyForOpen() const override {
|
bool isReadyForOpen() const override {
|
||||||
return _data->loaded();
|
return _data->loaded();
|
||||||
@ -263,7 +263,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool skipBubbleTail() const override {
|
bool skipBubbleTail() const override {
|
||||||
return isBubbleBottom();
|
return isBubbleBottom() && _caption.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -491,7 +491,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool skipBubbleTail() const override {
|
bool skipBubbleTail() const override {
|
||||||
return isBubbleBottom();
|
return isBubbleBottom() && _caption.isEmpty();
|
||||||
}
|
}
|
||||||
bool isReadyForOpen() const override {
|
bool isReadyForOpen() const override {
|
||||||
return _data->loaded();
|
return _data->loaded();
|
||||||
|
@ -51,11 +51,13 @@ StorageImages storageImages;
|
|||||||
|
|
||||||
int64 globalAcquiredSize = 0;
|
int64 globalAcquiredSize = 0;
|
||||||
|
|
||||||
constexpr uint64 BlurredCacheSkip = 0x1000000000000000ULL;
|
uint64 PixKey(int width, int height, ImagePixOptions options) {
|
||||||
constexpr uint64 ColoredCacheSkip = 0x2000000000000000ULL;
|
return static_cast<uint64>(width) | (static_cast<uint64>(height) << 24) | (static_cast<uint64>(options) << 48);
|
||||||
constexpr uint64 BlurredColoredCacheSkip = 0x3000000000000000ULL;
|
}
|
||||||
constexpr uint64 RoundedCacheSkip = 0x4000000000000000ULL;
|
|
||||||
constexpr uint64 CircledCacheSkip = 0x5000000000000000ULL;
|
uint64 SinglePixKey(ImagePixOptions options) {
|
||||||
|
return PixKey(0, 0, options);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -113,18 +115,18 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
uint64 k = (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Smooth | ImagePixOption::None;
|
||||||
Sizes::const_iterator i = _sizesCache.constFind(k);
|
auto k = PixKey(w, h, options);
|
||||||
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto options = ImagePixOption::Smooth | ImagePixOption::None;
|
auto p = pixNoCache(w, h, options);
|
||||||
auto p = pixNoCache(w, h, ImagePixOption::Smooth);
|
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
||||||
@ -136,29 +138,29 @@ const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, Imag
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
auto k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Smooth | ImagePixOption::None;
|
||||||
|
auto cornerOptions = [](ImageRoundCorners corners) {
|
||||||
|
return (corners & ImageRoundCorner::TopLeft ? ImagePixOption::RoundedTopLeft : ImagePixOption::None)
|
||||||
|
| (corners & ImageRoundCorner::TopRight ? ImagePixOption::RoundedTopRight : ImagePixOption::None)
|
||||||
|
| (corners & ImageRoundCorner::BottomLeft ? ImagePixOption::RoundedBottomLeft : ImagePixOption::None)
|
||||||
|
| (corners & ImageRoundCorner::BottomRight ? ImagePixOption::RoundedBottomRight : ImagePixOption::None);
|
||||||
|
};
|
||||||
|
if (radius == ImageRoundRadius::Large) {
|
||||||
|
options |= ImagePixOption::RoundedLarge | cornerOptions(corners);
|
||||||
|
} else if (radius == ImageRoundRadius::Small) {
|
||||||
|
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
||||||
|
}
|
||||||
|
auto k = PixKey(w, h, options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto options = ImagePixOption::Smooth | ImagePixOption::None;
|
|
||||||
auto cornerOptions = [](ImageRoundCorners corners) {
|
|
||||||
return (corners & ImageRoundCorner::TopLeft ? ImagePixOption::RoundedTopLeft : ImagePixOption::None)
|
|
||||||
| (corners & ImageRoundCorner::TopRight ? ImagePixOption::RoundedTopRight : ImagePixOption::None)
|
|
||||||
| (corners & ImageRoundCorner::BottomLeft ? ImagePixOption::RoundedBottomLeft : ImagePixOption::None)
|
|
||||||
| (corners & ImageRoundCorner::BottomRight ? ImagePixOption::RoundedBottomRight : ImagePixOption::None);
|
|
||||||
};
|
|
||||||
if (radius == ImageRoundRadius::Large) {
|
|
||||||
options |= ImagePixOption::RoundedLarge | cornerOptions(corners);
|
|
||||||
} else if (radius == ImageRoundRadius::Small) {
|
|
||||||
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
|
||||||
}
|
|
||||||
auto p = pixNoCache(w, h, options);
|
auto p = pixNoCache(w, h, options);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixCircled(int32 w, int32 h) const {
|
const QPixmap &Image::pixCircled(int32 w, int32 h) const {
|
||||||
@ -170,18 +172,18 @@ const QPixmap &Image::pixCircled(int32 w, int32 h) const {
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
auto k = CircledCacheSkip | (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Smooth | ImagePixOption::Circled;
|
||||||
|
auto k = PixKey(w, h, options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto options = ImagePixOption::Smooth | ImagePixOption::Circled;
|
|
||||||
auto p = pixNoCache(w, h, options);
|
auto p = pixNoCache(w, h, options);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
|
const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
|
||||||
@ -193,18 +195,18 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
auto k = BlurredCacheSkip | (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Smooth | ImagePixOption::Blurred;
|
||||||
|
auto k = PixKey(w, h, options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto options = ImagePixOption::Smooth | ImagePixOption::Blurred;
|
|
||||||
auto p = pixNoCache(w, h, options);
|
auto p = pixNoCache(w, h, options);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixColored(const style::color &add, int32 w, int32 h) const {
|
const QPixmap &Image::pixColored(const style::color &add, int32 w, int32 h) const {
|
||||||
@ -216,17 +218,18 @@ const QPixmap &Image::pixColored(const style::color &add, int32 w, int32 h) cons
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
auto k = ColoredCacheSkip | (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Smooth | ImagePixOption::Colored;
|
||||||
|
auto k = PixKey(w, h, options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto p = pixColoredNoCache(add, w, h, true);
|
auto p = pixColoredNoCache(add, w, h, true);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, ImagePixOption::Smooth | ImagePixOption::None });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32 h) const {
|
const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32 h) const {
|
||||||
@ -238,17 +241,18 @@ const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32
|
|||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
}
|
}
|
||||||
auto k = BlurredColoredCacheSkip | (uint64(w) << 32) | uint64(h);
|
auto options = ImagePixOption::Blurred | ImagePixOption::Smooth | ImagePixOption::Colored;
|
||||||
|
auto k = PixKey(w, h, options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend()) {
|
if (i == _sizesCache.cend()) {
|
||||||
auto p = pixBlurredColoredNoCache(add, w, h);
|
auto p = pixBlurredColoredNoCache(add, w, h);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, ImagePixOption::Blurred | ImagePixOption::Smooth });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
||||||
@ -274,20 +278,20 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im
|
|||||||
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto k = 0ULL;
|
auto k = SinglePixKey(options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend() || i->pix.width() != (outerw * cIntRetinaFactor()) || i->pix.height() != (outerh * cIntRetinaFactor()) || i->options != options) {
|
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
|
||||||
if (i != _sizesCache.cend()) {
|
if (i != _sizesCache.cend()) {
|
||||||
globalAcquiredSize -= int64(i->pix.width()) * i->pix.height() * 4;
|
globalAcquiredSize -= int64(i->width()) * i->height() * 4;
|
||||||
}
|
}
|
||||||
auto p = pixNoCache(w, h, options, outerw, outerh);
|
auto p = pixNoCache(w, h, options, outerw, outerh);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners) const {
|
||||||
@ -313,20 +317,20 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh,
|
|||||||
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
options |= ImagePixOption::RoundedSmall | cornerOptions(corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto k = BlurredCacheSkip | 0ULL;
|
auto k = SinglePixKey(options);
|
||||||
auto i = _sizesCache.constFind(k);
|
auto i = _sizesCache.constFind(k);
|
||||||
if (i == _sizesCache.cend() || i->pix.width() != (outerw * cIntRetinaFactor()) || i->pix.height() != (outerh * cIntRetinaFactor()) || i->options != options) {
|
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
|
||||||
if (i != _sizesCache.cend()) {
|
if (i != _sizesCache.cend()) {
|
||||||
globalAcquiredSize -= int64(i->pix.width()) * i->pix.height() * 4;
|
globalAcquiredSize -= int64(i->width()) * i->height() * 4;
|
||||||
}
|
}
|
||||||
auto p = pixNoCache(w, h, options, outerw, outerh);
|
auto p = pixNoCache(w, h, options, outerw, outerh);
|
||||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _sizesCache.insert(k, { p, options });
|
i = _sizesCache.insert(k, p);
|
||||||
if (!p.isNull()) {
|
if (!p.isNull()) {
|
||||||
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
globalAcquiredSize += int64(p.width()) * p.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i.value().pix;
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -734,9 +738,9 @@ void Image::restore() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Image::invalidateSizeCache() const {
|
void Image::invalidateSizeCache() const {
|
||||||
for (auto &size : _sizesCache) {
|
for (auto &pix : _sizesCache) {
|
||||||
if (!size.pix.isNull()) {
|
if (!pix.isNull()) {
|
||||||
globalAcquiredSize -= int64(size.pix.width()) * size.pix.height() * 4;
|
globalAcquiredSize -= int64(pix.width()) * pix.height() * 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_sizesCache.clear();
|
_sizesCache.clear();
|
||||||
|
@ -135,6 +135,7 @@ enum class ImagePixOption {
|
|||||||
RoundedTopRight = 0x040,
|
RoundedTopRight = 0x040,
|
||||||
RoundedBottomLeft = 0x080,
|
RoundedBottomLeft = 0x080,
|
||||||
RoundedBottomRight = 0x100,
|
RoundedBottomRight = 0x100,
|
||||||
|
Colored = 0x200,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ImagePixOptions, ImagePixOption);
|
Q_DECLARE_FLAGS(ImagePixOptions, ImagePixOption);
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(ImagePixOptions);
|
Q_DECLARE_OPERATORS_FOR_FLAGS(ImagePixOptions);
|
||||||
@ -248,12 +249,7 @@ protected:
|
|||||||
mutable QPixmap _data;
|
mutable QPixmap _data;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using Sizes = QMap<uint64, QPixmap>;
|
||||||
struct Size {
|
|
||||||
QPixmap pix;
|
|
||||||
ImagePixOptions options;
|
|
||||||
};
|
|
||||||
typedef QMap<uint64, Size> Sizes;
|
|
||||||
mutable Sizes _sizesCache;
|
mutable Sizes _sizesCache;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user