PictureRenderer.cpp revision 163b56734fe01c088581895a8e0b65ddf1cb4fa5
1#include "PictureRenderer.h"
2#include "SamplePipeControllers.h"
3#include "SkCanvas.h"
4#include "SkDevice.h"
5#include "SkGPipe.h"
6#include "SkPicture.h"
7#include "SkTDArray.h"
8#include "SkTypes.h"
9#include "picture_utils.h"
10
11namespace sk_tools {
12
13enum {
14    kDefaultTileWidth = 256,
15    kDefaultTileHeight = 256
16};
17
18void PipePictureRenderer::render(SkPicture* pict, SkCanvas* canvas) {
19    PipeController pipeController(canvas);
20    SkGPipeWriter writer;
21    SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
22    pipeCanvas->drawPicture(*pict);
23    writer.endRecording();
24}
25
26void SimplePictureRenderer::render(SkPicture* pict, SkCanvas* canvas) {
27    canvas->drawPicture(*pict);
28}
29
30TiledPictureRenderer::TiledPictureRenderer()
31    : fTileWidth(kDefaultTileWidth)
32    , fTileHeight(kDefaultTileHeight) {}
33
34void TiledPictureRenderer::init(const SkPicture& pict) {
35    deleteTiles();
36
37    if (fTileWidthPercentage > 0) {
38        fTileWidth = sk_float_ceil2int(fTileWidthPercentage * pict.width() / 100);
39    }
40    if (fTileHeightPercentage > 0) {
41        fTileHeight = sk_float_ceil2int(fTileHeightPercentage * pict.height() / 100);
42    }
43
44    setupTiles(pict);
45}
46
47void TiledPictureRenderer::render(SkPicture* pict, SkCanvas* canvas) {
48    drawTiles(pict);
49
50    copyTilesToCanvas(*pict, canvas);
51}
52
53TiledPictureRenderer::~TiledPictureRenderer() {
54    deleteTiles();
55}
56
57void TiledPictureRenderer::clipTile(const SkPicture& picture, const TileInfo& tile) {
58    SkRect clip = SkRect::MakeWH(SkIntToScalar(picture.width()),
59                                 SkIntToScalar(picture.height()));
60    tile.fCanvas->clipRect(clip);
61}
62
63void TiledPictureRenderer::addTile(const SkPicture& picture, int tile_x_start, int tile_y_start) {
64    TileInfo* tile = fTiles.push();
65
66    tile->fBitmap = SkNEW(SkBitmap);
67    sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight);
68
69    tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap)));
70    tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
71    clipTile(picture, *tile);
72}
73
74void TiledPictureRenderer::setupTiles(const SkPicture& picture) {
75    for (int tile_y_start = 0; tile_y_start < picture.height();
76         tile_y_start += fTileHeight) {
77        for (int tile_x_start = 0; tile_x_start < picture.width();
78             tile_x_start += fTileWidth) {
79            addTile(picture, tile_x_start, tile_y_start);
80        }
81    }
82}
83
84void TiledPictureRenderer::deleteTiles() {
85    for (int i = 0; i < fTiles.count(); ++i) {
86        SkDELETE(fTiles[i].fCanvas);
87        SkDELETE(fTiles[i].fBitmap);
88    }
89
90    fTiles.reset();
91}
92
93void TiledPictureRenderer::drawTiles(SkPicture* pict) {
94    for (int i = 0; i < fTiles.count(); ++i) {
95        fTiles[i].fCanvas->drawPicture(*pict);
96    }
97}
98
99void TiledPictureRenderer::copyTilesToCanvas(const SkPicture& pict, SkCanvas* destination) {
100    int tile_index = 0;
101    for (int tile_y_start = 0; tile_y_start < pict.height();
102         tile_y_start += fTileHeight) {
103        for (int tile_x_start = 0; tile_x_start < pict.width();
104             tile_x_start += fTileWidth) {
105            SkASSERT(tile_index < fTiles.count());
106            SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
107            destination->drawBitmap(source,
108                                    SkIntToScalar(tile_x_start),
109                                    SkIntToScalar(tile_y_start));
110            ++tile_index;
111        }
112    }
113}
114
115}
116