Speed up cover rendering by caching QPixmaps

This commit is contained in:
Kovid Goyal 2013-08-02 09:49:52 +05:30
parent 2e6b37ee7f
commit 3ae7205720

View File

@ -15,7 +15,7 @@ from functools import wraps
from PyQt4.Qt import ( from PyQt4.Qt import (
QListView, QSize, QStyledItemDelegate, QModelIndex, Qt, QImage, pyqtSignal, QListView, QSize, QStyledItemDelegate, QModelIndex, Qt, QImage, pyqtSignal,
QPalette, QColor, QItemSelection) QPalette, QColor, QItemSelection, QPixmap)
from calibre import fit_image from calibre import fit_image
@ -108,18 +108,22 @@ class CoverCache(dict):
with self.lock: with self.lock:
self.items.pop(book_id, None) self.items.pop(book_id, None)
def __call__(self, key): def __getitem__(self, key):
' Must be called in the GUI thread '
with self.lock: with self.lock:
ans = self.items.pop(key, False) ans = self.items.pop(key, False) # pop() so that item is moved to the top
if ans is not False: if ans is not False:
if isinstance(ans, QImage):
# Convert to QPixmap, since rendering QPixmap is much
# faster
ans = QPixmap.fromImage(ans)
self.items[key] = ans self.items[key] = ans
if len(self.items) > self.limit:
del self.items[next(self.items.iterkeys())]
return ans return ans
def set(self, key, val): def set(self, key, val):
with self.lock: with self.lock:
self.items.pop(key, None) # pop() so that item is moved to the top
self.items[key] = val self.items[key] = val
if len(self.items) > self.limit: if len(self.items) > self.limit:
del self.items[next(self.items.iterkeys())] del self.items[next(self.items.iterkeys())]
@ -152,7 +156,7 @@ class CoverDelegate(QStyledItemDelegate):
except (ValueError, IndexError, KeyError): except (ValueError, IndexError, KeyError):
return return
db = db.new_api db = db.new_api
cdata = self.cover_cache(book_id) cdata = self.cover_cache[book_id]
painter.save() painter.save()
try: try:
rect = option.rect rect = option.rect
@ -166,7 +170,7 @@ class CoverDelegate(QStyledItemDelegate):
dx = max(0, int((rect.width() - cdata.width())/2.0)) dx = max(0, int((rect.width() - cdata.width())/2.0))
dy = max(0, rect.height() - cdata.height()) dy = max(0, rect.height() - cdata.height())
rect.adjust(dx, dy, -dx, 0) rect.adjust(dx, dy, -dx, 0)
painter.drawImage(rect, cdata) painter.drawPixmap(rect, cdata)
finally: finally:
painter.restore() painter.restore()