Use tiles only when it's necessary

In other words: don't use tiles when the page is not big enough
remotes/origin/KDE/4.10
Mailson Menezes 14 years ago
parent de2ee00ff8
commit 9c09eb938e
  1. 42
      core/document.cpp
  2. 23
      core/page.cpp
  3. 4
      core/page.h
  4. 6
      core/tilesmanager.cpp
  5. 2
      core/tilesmanager.h
  6. 52
      ui/pageview.cpp

@ -891,6 +891,8 @@ void DocumentPrivate::sendGeneratorRequest()
const NormalizedRect visibleRect = ( r ? r->normalizedRect() : NormalizedRect() );
const QRect requestRect = !visibleRect.isNull() ? visibleRect.geometry( r->width(), r->height() ) : QRect( 0, 0, r->width(), r->height() );
TilesManager *tilesManager = r->page()->tilesManager( r->id() );
if (!r)
m_pixmapRequestsStack.pop_back();
@ -900,7 +902,42 @@ void DocumentPrivate::sendGeneratorRequest()
m_pixmapRequestsStack.pop_back();
delete r;
}
else if ( (long)requestRect.width() * (long)requestRect.height() > 20000000L )
else if ( !tilesManager && r->id() == PAGEVIEW_ID && (long)r->width() * (long)r->height() > 8000000L )
{
// if the image is too big. start using tiles
kWarning(OkularDebug).nospace() << "Running out of memory on page " << r->pageNumber()
<< " (" << r->width() << "x" << r->height() << " px);";
kWarning(OkularDebug) << "start using tiles.";
// fill the tiles manager with the last rendered pixmap
const QPixmap *pixmap = r->page()->_o_nearestPixmap( r->id(), r->width(), r->height() );
if ( pixmap )
{
tilesManager = new TilesManager( pixmap->width(), pixmap->height() );
tilesManager->setPixmap( pixmap, NormalizedRect( 0, 0, 1, 1 ) );
tilesManager->setWidth( r->width() );
tilesManager->setHeight( r->height() );
}
else
{
// create new tiles manager
tilesManager = new TilesManager( r->width(), r->height() );
}
r->page()->setTilesManager( r->id(), tilesManager );
request = r;
}
else if ( tilesManager && (long)r->width() * (long)r->height() < 6000000L )
{
kWarning(OkularDebug).nospace() << "Stop using tiles on page " << r->pageNumber()
<< " (" << r->width() << "x" << r->height() << " px);";
// page is too small. stop using tiles.
r->setNormalizedRect( NormalizedRect() );
request = r;
}
else if ( tilesManager && (long)requestRect.width() * (long)requestRect.height() > 20000000L )
{
m_pixmapRequestsStack.pop_back();
if ( !m_warnedOutOfMemory )
@ -932,7 +969,8 @@ void DocumentPrivate::sendGeneratorRequest()
// submit the request to the generator
if ( m_generator->canGeneratePixmap() )
{
kDebug(OkularDebug).nospace() << "sending request id=" << request->id() << " " <<request->width() << "x" << request->height() << "@" << request->pageNumber() << " async == " << request->asynchronous();
QRect requestRect = request->normalizedRect().isNull() ? QRect(0, 0, request->width(), request->height() ) : request->normalizedRect().geometry( request->width(), request->height() );
kDebug(OkularDebug).nospace() << "sending request id=" << request->id() << " " <<requestRect.width() << "x" << requestRect.height() << "@" << request->pageNumber() << " async == " << request->asynchronous();
m_pixmapRequestsStack.removeAll ( request );
if ( (int)m_rotation % 2 )

@ -205,15 +205,9 @@ void Page::setBoundingBox( const NormalizedRect& bbox )
bool Page::hasPixmap( int id, int width, int height, const NormalizedRect &rect ) const
{
if ( id == PAGEVIEW_ID )
TilesManager *tm = tilesManager( id );
if ( tm )
{
TilesManager *tm = tilesManager( id );
if ( !tm )
{
tm = new TilesManager( width, height );
d->m_tilesManagers.insert( id, tm );
}
if ( width != tm->width() || height != tm->height() )
{
tm->setWidth( width );
@ -492,6 +486,7 @@ void Page::setPixmap( int id, QPixmap *pixmap, const NormalizedRect &rect )
if ( tm )
{
tm->setPixmap( pixmap, rect );
delete pixmap;
return;
}
@ -962,14 +957,14 @@ TilesManager *Page::tilesManager( int id ) const
return tilesManager;
}
void Page::deleteTilesManagers()
void Page::setTilesManager( int id, TilesManager *tm )
{
QMap< int, TilesManager* >::iterator itTilesManager = d->m_tilesManagers.begin();
while ( itTilesManager != d->m_tilesManagers.end() )
QMap< int, TilesManager* >::const_iterator itTilesManager = d->m_tilesManagers.constFind( id );
if ( itTilesManager != d->m_tilesManagers.constEnd() )
{
delete (*itTilesManager);
itTilesManager++;
if ( *itTilesManager )
delete *itTilesManager;
}
d->m_tilesManagers.clear();
d->m_tilesManagers.insert( id, tm );
}

@ -364,9 +364,9 @@ class OKULAR_EXPORT Page
TilesManager *tilesManager( int id ) const;
/**
* Deletes all tiles managers
* Sets a tiles manager for the given @p id
*/
void deleteTilesManagers();
void setTilesManager( int id, TilesManager *tm );
private:
PagePrivate* const d;

@ -29,7 +29,7 @@ TilesManager::~TilesManager()
{
for ( int i = 0; i < 16; ++i )
{
if ( m_tiles[ i ] )
if ( m_tiles[ i ].pixmap )
delete m_tiles[ i ].pixmap;
}
}
@ -60,7 +60,7 @@ void TilesManager::setHeight( int height )
}
}
void TilesManager::setPixmap( QPixmap *pixmap, const NormalizedRect &rect )
void TilesManager::setPixmap( const QPixmap *pixmap, const NormalizedRect &rect )
{
const double dim = 0.25;
int left = qCeil( rect.left/dim );
@ -84,8 +84,6 @@ void TilesManager::setPixmap( QPixmap *pixmap, const NormalizedRect &rect )
m_tiles[ index ].dirty = false;
}
}
delete pixmap;
}
bool TilesManager::hasPixmap( const NormalizedRect &rect )

@ -34,7 +34,7 @@ class OKULAR_EXPORT TilesManager
TilesManager( int width, int height );
virtual ~TilesManager();
void setPixmap( QPixmap *pixmap, const NormalizedRect &rect );
void setPixmap( const QPixmap *pixmap, const NormalizedRect &rect );
bool hasPixmap( const NormalizedRect &rect );
QList<Tile> tilesAt( const NormalizedRect &rect ) const;

@ -3126,21 +3126,25 @@ void PageView::drawDocumentOnPainter( const QRect & contentsRect, QPainter * p )
}
}
QVector< Okular::VisiblePageRect * >::const_iterator vIt = d->document->visiblePageRects().constBegin(), vEnd = d->document->visiblePageRects().constEnd();
Okular::NormalizedRect crop;
for ( ; vIt != vEnd; ++vIt )
if ( item->page()->tilesManager( PAGEVIEW_ID ) )
{
Okular::VisiblePageRect *vItem = *vIt;
if ( vItem->pageNumber == item->pageNumber() )
QVector< Okular::VisiblePageRect * >::const_iterator vIt = d->document->visiblePageRects().constBegin(), vEnd = d->document->visiblePageRects().constEnd();
for ( ; vIt != vEnd; ++vIt )
{
crop = item->crop() & vItem->rect;
if ( crop.isNull() )
crop = item->crop();
break;
Okular::VisiblePageRect *vItem = *vIt;
if ( vItem->pageNumber == item->pageNumber() )
{
crop = item->crop() & vItem->rect;
break;
}
}
}
if ( crop.isNull() )
crop = item->crop();
// draw the page using the PagePainter with all flags active
if ( contentsRect.intersects( itemGeometry ) )
{
@ -3984,19 +3988,29 @@ void PageView::slotRequestVisiblePixmaps( int newValue )
#ifdef PAGEVIEW_DEBUG
kWarning() << "rerequesting visible pixmaps for page" << i->pageNumber() << "!";
#endif
QList<Okular::Tile> tiles = i->page()->tilesManager( PAGEVIEW_ID )->tilesAt( vItem->rect );
QList<Okular::Tile>::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd();
while ( tIt != tEnd )
Okular::TilesManager *tilesManager = i->page()->tilesManager( PAGEVIEW_ID );
if ( tilesManager )
{
Okular::Tile tile = *tIt;
if ( !tile.isValid() )
QList<Okular::Tile> tiles = i->page()->tilesManager( PAGEVIEW_ID )->tilesAt( vItem->rect );
QList<Okular::Tile>::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd();
while ( tIt != tEnd )
{
Okular::PixmapRequest * p = new Okular::PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true );
p->setNormalizedRect( tile.rect );
requestedPixmaps.push_back( p );
Okular::Tile tile = *tIt;
if ( !tile.isValid() )
{
Okular::PixmapRequest * p = new Okular::PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true );
p->setNormalizedRect( tile.rect );
requestedPixmaps.push_back( p );
}
tIt++;
}
tIt++;
}
else
{
Okular::PixmapRequest * p = new Okular::PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true );
requestedPixmaps.push_back( p );
}
}

Loading…
Cancel
Save