/* Function Definitions */ void b_log2(const double x[2], double f[2]) { int k; for (k = 0; k < 2; k++) { f[k] = scalar_log2(x[k]); } }
// The goal of the powers of two tiles is to minimize the amount of wasted tile // space in the width-wise direction and then minimize the number of tiles. The // constraints are that every tile must have a pixel width that is a power of // two and also be of some minimal width (that is also a power of two). // // This is solved by first taking our picture size and rounding it up to the // multiple of the minimal width. The binary representation of this rounded // value gives us the tiles we need: a bit of value one means we need a tile of // that size. void TiledPictureRenderer::setupPowerOf2Tiles() { // Only use enough tiles to cover the viewport const int width = this->getViewWidth(); const int height = this->getViewHeight(); int rounded_value = width; if (width % fTileMinPowerOf2Width != 0) { rounded_value = width - (width % fTileMinPowerOf2Width) + fTileMinPowerOf2Width; } int num_bits = SkScalarCeilToInt(scalar_log2(SkIntToScalar(width))); int largest_possible_tile_size = 1 << num_bits; fTilesX = fTilesY = 0; // The tile height is constant for a particular picture. for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) { fTilesY++; int tile_x_start = 0; int current_width = largest_possible_tile_size; // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough // to draw each tile. fTileWidth = current_width; while (current_width >= fTileMinPowerOf2Width) { // It is very important this is a bitwise AND. if (current_width & rounded_value) { if (0 == tile_y_start) { // Only count tiles in the X direction on the first pass. fTilesX++; } *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), SkIntToScalar(tile_y_start), SkIntToScalar(current_width), SkIntToScalar(fTileHeight)); tile_x_start += current_width; } current_width >>= 1; } } }