Skip to content

Commit

Permalink
Eliminate flicker when zooming in our out at soom levels less than 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
ajclinto committed Dec 13, 2015
1 parent 2b92855 commit 67c06d8
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 8 deletions.
1 change: 1 addition & 0 deletions DisplayLayout.C
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ DisplayLayout::fillImage(
GLImage<TYPE> &image, const SOURCE &src, int64 coff, int64 roff) const;

INST_FUNC(uint32, StateSource)
INST_FUNC(uint32, SampledStateSource)
INST_FUNC(uint64, AddressSource)
INST_FUNC(uint32, IntervalSource<MMapInfo>)
INST_FUNC(uint32, IntervalSource<StackInfo>)
Expand Down
50 changes: 50 additions & 0 deletions DisplayLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,56 @@ class StateSource {
MemoryState &myState;
};

// Fill State values from the given MemoryState, sampling based on the given
// zoom level
class SampledStateSource {
public:
SampledStateSource(MemoryState &state, int zoom)
: myState(state)
, myZoom(zoom) {}

struct Page {
Page(MemoryState::DisplayPage page, int zoom)
: myPage(page)
, myZoom(zoom) {}

uint64 size() const { return SYSmax(myPage.size() >> myZoom, 1ull); }

MemoryState::DisplayPage myPage;
int myZoom;
};

Page getPage(uint64 addr, uint64, uint64 &off) const
{
auto page = myState.getPage(addr << myZoom, off);
off >>= myZoom;
return Page(page, myZoom);
}

inline bool exists(const Page &page) const
{ return page.myPage.exists(); }

inline void setScanline(uint32 *scan,
Page &page, uint64 off, int n) const
{
const uint32 *state = (const uint32 *)page.myPage.stateArray() + (off << myZoom);
for (int i = 0; i < n; i++)
scan[i] = state[i << myZoom];
}
inline void gatherScanline(uint32 *scan,
Page &page, uint64 off,
const int *lut, int n) const
{
const uint32 *state = (const uint32 *)page.myPage.stateArray() + (off << myZoom);
for (int i = 0; i < n; i++)
scan[i] = state[lut[i] << myZoom];
}

private:
MemoryState &myState;
int myZoom;
};

// Fill memory addresses
class AddressSource {
public:
Expand Down
3 changes: 3 additions & 0 deletions MemoryState.C
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

MemoryState::MemoryState(int ignorebits)
: myTime(2)
, mySampling(false)
, myIgnoreBits(ignorebits)
, myBottomBits(SYSmax(theAllBits-ignorebits, thePageBits))
, myHead(myBottomBits, 0, 0)
Expand Down Expand Up @@ -196,6 +197,8 @@ MemoryState::downsample(const MemoryState &state)
QThreadPool::globalInstance()->start(task);

QThreadPool::globalInstance()->waitForDone();

mySampling = false;
}

void
Expand Down
5 changes: 5 additions & 0 deletions MemoryState.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ class MemoryState {
void downsample(const MemoryState &state);
void downsamplePage(const DisplayPage &page, int shift, bool fast);

// Set a flag that is reset to false when downsample is complete
void setSamplingInProgress() { mySampling = true; }
bool isSamplingInProgress() const { return mySampling; }

private:
class StackInfoUpdater {
bool myFull;
Expand Down Expand Up @@ -369,6 +373,7 @@ class MemoryState {
private:
QMutex myWriteLock;
uint32 myTime; // Rolling counter
bool mySampling;

// The number of low-order bits to ignore. This value determines the
// resolution and memory use for the profile.
Expand Down
27 changes: 19 additions & 8 deletions Window.C
Original file line number Diff line number Diff line change
Expand Up @@ -665,33 +665,43 @@ MemViewWidget::paintGL()
fprintf(stderr, "interval %f time ", myPaintInterval.lap());
#endif

myDisplay.update(
*myState, *myMMapMap, width(), myImage.width(), myZoom);

int64 roff = myHScrollBar->value();
int64 coff = myVScrollBar->value();

#ifdef USE_PBUFFER
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, myPixelBuffer);

myImage.setData((uint32 *)
glMapBufferARB(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
#endif

myDisplay.update(*myState, *myMMapMap, width(), myImage.width(), myZoom);
switch (myDisplayMode)
{
case 3:
myDisplay.fillImage(myImage, IntervalSource<MMapInfo>(
*myMMapMap, 0, myZoomState->getIgnoreBits()),
myHScrollBar->value(),
myVScrollBar->value());
roff, coff);
break;
case 4:
myDisplay.fillImage(myImage, IntervalSource<StackInfo>(
*myStackTrace, myStackSelection,
myZoomState->getIgnoreBits()),
myHScrollBar->value(),
myVScrollBar->value());
roff, coff);
break;
default:
myDisplay.fillImage(myImage, StateSource(*myZoomState),
myHScrollBar->value(),
myVScrollBar->value());
if (myZoom <= 0 || !myZoomState->isSamplingInProgress())
{
myDisplay.fillImage(myImage, StateSource(*myZoomState),
roff, coff);
}
else
{
myDisplay.fillImage(myImage, SampledStateSource(*myState, myZoom),
roff, coff);
}
break;
}

Expand Down Expand Up @@ -1194,6 +1204,7 @@ MemViewWidget::changeZoom(int zoom)
if (zoom > 0)
{
myZoomState = new MemoryState(myState->getIgnoreBits()+zoom);
myZoomState->setSamplingInProgress();
myLoader->setZoomState(myZoomState);
}
else
Expand Down

0 comments on commit 67c06d8

Please sign in to comment.