Program: 38671
Project: 38671
Buggy source:
private void layoutTiles(int centerX,int centerY,float scale,int rotation){
  int width=getWidth();
  int height=getHeight();
  int fromLevel;
  int endLevel;
  mLevel=Utils.clamp(Utils.floorLog2(1f / scale),0,mLevelCount);
  if (mLevel != mLevelCount) {
    Rect range=mTileRange;
    getRange(range,centerX,centerY,mLevel,scale,rotation);
    mOffsetX=Math.round(width / 2f + (range.left - centerX) * scale);
    mOffsetY=Math.round(height / 2f + (range.top - centerY) * scale);
    fromLevel=scale * (1 << mLevel) > 0.75f ? mLevel - 1 : mLevel;
  }
 else {
    fromLevel=mLevel - 2;
    mOffsetX=Math.round(width / 2f - centerX * scale);
    mOffsetY=Math.round(height / 2f - centerY * scale);
  }
  fromLevel=Math.max(0,Math.min(fromLevel,mLevelCount - 2));
  endLevel=Math.min(fromLevel + 2,mLevelCount);
  Rect range[]=mActiveRange;
  for (int i=fromLevel; i < endLevel; ++i) {
    getRange(range[i - fromLevel],centerX,centerY,i,rotation);
  }
  if (rotation % 90 != 0)   return;
synchronized (this) {
    mDecodeQueue.clean();
    mUploadQueue.clean();
    mBackgroundTileUploaded=false;
  }
  int n=mActiveTiles.size();
  for (int i=0; i < n; i++) {
    Tile tile=mActiveTiles.valueAt(i);
    int level=tile.mTileLevel;
    if (level < fromLevel || level >= endLevel || !range[level - fromLevel].contains(tile.mX,tile.mY)) {
      mActiveTiles.removeAt(i);
      i--;
      n--;
      recycleTile(tile);
    }
  }
  for (int i=fromLevel; i < endLevel; ++i) {
    int size=TILE_SIZE << i;
    Rect r=range[i - fromLevel];
    for (int y=r.top, bottom=r.bottom; y < bottom; y+=size) {
      for (int x=r.left, right=r.right; x < right; x+=size) {
        activateTile(x,y,i);
      }
    }
  }
  invalidate();
}

Fixed version (ground truth):
private void layoutTiles(int centerX,int centerY,float scale,int rotation){
  int width=getWidth();
  int height=getHeight();
  int fromLevel;
  int endLevel;
  mLevel=Utils.clamp(Utils.floorLog2(1f / scale),0,mLevelCount);
  if (mLevel != mLevelCount) {
    Rect range=mTileRange;
    getRange(range,centerX,centerY,mLevel,scale,rotation);
    mOffsetX=Math.round(width / 2f + (range.left - centerX) * scale);
    mOffsetY=Math.round(height / 2f + (range.top - centerY) * scale);
    fromLevel=scale * (1 << mLevel) > 0.75f ? mLevel - 1 : mLevel;
  }
 else {
    fromLevel=mLevel - 2;
    mOffsetX=Math.round(width / 2f - centerX * scale);
    mOffsetY=Math.round(height / 2f - centerY * scale);
  }
  fromLevel=Math.max(0,Math.min(fromLevel,mLevelCount - 2));
  endLevel=Math.min(fromLevel + 2,mLevelCount);
  Rect range[]=mActiveRange;
  for (int i=fromLevel; i < endLevel; ++i) {
    getRange(range[i - fromLevel],centerX,centerY,i,rotation);
  }
  if (rotation % 90 != 0)   return;
synchronized (this) {
    mDecodeQueue.clean();
    mUploadQueue.clean();
    mBackgroundTileUploaded=false;
    int n=mActiveTiles.size();
    for (int i=0; i < n; i++) {
      Tile tile=mActiveTiles.valueAt(i);
      int level=tile.mTileLevel;
      if (level < fromLevel || level >= endLevel || !range[level - fromLevel].contains(tile.mX,tile.mY)) {
        mActiveTiles.removeAt(i);
        i--;
        n--;
        recycleTile(tile);
      }
    }
  }
  for (int i=fromLevel; i < endLevel; ++i) {
    int size=TILE_SIZE << i;
    Rect r=range[i - fromLevel];
    for (int y=r.top, bottom=r.bottom; y < bottom; y+=size) {
      for (int x=r.left, right=r.right; x < right; x+=size) {
        activateTile(x,y,i);
      }
    }
  }
  invalidate();
}