#include "PictureRenderer.h" #include "SamplePipeControllers.h" #include "SkCanvas.h" #include "SkDevice.h" #include "SkGPipe.h" #include "SkPicture.h" #include "SkTDArray.h" #include "SkTypes.h" #include "picture_utils.h" namespace sk_tools { enum { kDefaultTileWidth = 256, kDefaultTileHeight = 256 }; void PipePictureRenderer::render(SkPicture* pict, SkCanvas* canvas) { PipeController pipeController(canvas); SkGPipeWriter writer; SkCanvas* pipeCanvas = writer.startRecording(&pipeController); pipeCanvas->drawPicture(*pict); writer.endRecording(); } void SimplePictureRenderer::render(SkPicture* pict, SkCanvas* canvas) { canvas->drawPicture(*pict); } TiledPictureRenderer::TiledPictureRenderer() : fTileWidth(kDefaultTileWidth) , fTileHeight(kDefaultTileHeight) {} void TiledPictureRenderer::init(const SkPicture& pict) { deleteTiles(); if (fTileWidthPercentage > 0) { fTileWidth = sk_float_ceil2int(fTileWidthPercentage * pict.width() / 100); } if (fTileHeightPercentage > 0) { fTileHeight = sk_float_ceil2int(fTileHeightPercentage * pict.height() / 100); } setupTiles(pict); } void TiledPictureRenderer::render(SkPicture* pict, SkCanvas* canvas) { for (int i = 0; i < fTiles.count(); ++i) { fTiles[i].fCanvas->drawPicture(*pict); } copyTilesToCanvas(*pict, canvas); } TiledPictureRenderer::~TiledPictureRenderer() { deleteTiles(); } void TiledPictureRenderer::clipTile(const SkPicture& picture, const TileInfo& tile) { SkRect clip = SkRect::MakeWH(SkIntToScalar(picture.width()), SkIntToScalar(picture.height())); tile.fCanvas->clipRect(clip); } void TiledPictureRenderer::addTile(const SkPicture& picture, int tile_x_start, int tile_y_start) { TileInfo* tile = fTiles.push(); tile->fBitmap = SkNEW(SkBitmap); sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight); tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap))); tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start)); clipTile(picture, *tile); } void TiledPictureRenderer::setupTiles(const SkPicture& picture) { for (int tile_y_start = 0; tile_y_start < picture.height(); tile_y_start += fTileHeight) { for (int tile_x_start = 0; tile_x_start < picture.width(); tile_x_start += fTileWidth) { addTile(picture, tile_x_start, tile_y_start); } } } void TiledPictureRenderer::deleteTiles() { for (int i = 0; i < fTiles.count(); ++i) { SkDELETE(fTiles[i].fCanvas); SkDELETE(fTiles[i].fBitmap); } fTiles.reset(); } void TiledPictureRenderer::copyTilesToCanvas(const SkPicture& pict, SkCanvas* destination) { int tile_index = 0; for (int tile_y_start = 0; tile_y_start < pict.height(); tile_y_start += fTileHeight) { for (int tile_x_start = 0; tile_x_start < pict.width(); tile_x_start += fTileWidth) { SkASSERT(tile_index < fTiles.count()); SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false); destination->drawBitmap(source, SkIntToScalar(tile_x_start), SkIntToScalar(tile_y_start)); ++tile_index; } } } }