PictureRenderer.cpp revision 9d696c0d04548520af08252e577d2ca88012a239
1451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "PictureRenderer.h"
2451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SamplePipeControllers.h"
3451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkCanvas.h"
4451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkDevice.h"
5451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkGPipe.h"
6451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkPicture.h"
7451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTDArray.h"
8451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTypes.h"
9451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "picture_utils.h"
10451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
11451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgnamespace sk_tools {
12451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
13451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgenum {
14451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    kDefaultTileWidth = 256,
15451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    kDefaultTileHeight = 256
16451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org};
17451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
189d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PictureRenderer::init(SkPicture* pict) {
199d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fPicture == NULL);
209d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fCanvas.get() == NULL);
219d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (fPicture != NULL || fCanvas.get() != NULL) {
229d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
239d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
249d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
259d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(pict != NULL);
269d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (pict == NULL) {
279d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
289d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
299d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
309d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    fPicture = pict;
319d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkBitmap bitmap;
329d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    sk_tools::setup_bitmap(&bitmap, fPicture->width(), fPicture->height());
339d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    fCanvas.reset(SkNEW_ARGS(SkCanvas, (bitmap)));
349d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org}
359d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
369d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PictureRenderer::end() {
379d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    fPicture = NULL;
389d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    fCanvas.reset(NULL);
399d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org}
409d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
419d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PipePictureRenderer::render() {
429d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fCanvas.get() != NULL);
439d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fPicture != NULL);
449d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (fCanvas.get() == NULL || fPicture == NULL) {
459d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
469d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
479d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
489d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    PipeController pipeController(fCanvas.get());
49451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    SkGPipeWriter writer;
50451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
519d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    pipeCanvas->drawPicture(*fPicture);
52451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    writer.endRecording();
53451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
54451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
559d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid SimplePictureRenderer::render() {
569d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fCanvas.get() != NULL);
579d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fPicture != NULL);
589d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (fCanvas.get() == NULL || fPicture == NULL) {
599d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
609d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
619d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
629d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    fCanvas->drawPicture(*fPicture);
63451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
64451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
65451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgTiledPictureRenderer::TiledPictureRenderer()
66451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    : fTileWidth(kDefaultTileWidth)
67451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    , fTileHeight(kDefaultTileHeight) {}
68451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
699d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::init(SkPicture* pict) {
709d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(pict != NULL);
719d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fTiles.count() == 0);
729d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (pict == NULL || fTiles.count() != 0) {
739d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
749d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
759d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
769d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->INHERITED::init(pict);
77cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org
78cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org    if (fTileWidthPercentage > 0) {
799d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        fTileWidth = sk_float_ceil2int(fTileWidthPercentage * fPicture->width() / 100);
80cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org    }
81cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org    if (fTileHeightPercentage > 0) {
829d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        fTileHeight = sk_float_ceil2int(fTileHeightPercentage * fPicture->height() / 100);
83cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org    }
84cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org
859d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->setupTiles();
86451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
87451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
889d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::render() {
899d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fCanvas.get() != NULL);
909d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkASSERT(fPicture != NULL);
919d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    if (fCanvas.get() == NULL || fPicture == NULL) {
929d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        return;
939d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    }
949d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org
959d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->drawTiles();
969d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->copyTilesToCanvas();
979d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org}
98451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
999d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::end() {
1009d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->deleteTiles();
1019d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->INHERITED::end();
102451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
103451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
104451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgTiledPictureRenderer::~TiledPictureRenderer() {
1059d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->deleteTiles();
106451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
107451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
1089d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::clipTile(const TileInfo& tile) {
1099d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
1109d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org                                 SkIntToScalar(fPicture->height()));
111451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    tile.fCanvas->clipRect(clip);
112451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
113451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
1149d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
115451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    TileInfo* tile = fTiles.push();
116451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
117451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    tile->fBitmap = SkNEW(SkBitmap);
118451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight);
119451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
120451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap)));
121451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
1229d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    this->clipTile(*tile);
123451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
124451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
1259d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::setupTiles() {
1269d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    for (int tile_y_start = 0; tile_y_start < fPicture->height();
127451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org         tile_y_start += fTileHeight) {
1289d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        for (int tile_x_start = 0; tile_x_start < fPicture->width();
129451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org             tile_x_start += fTileWidth) {
1309d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org            this->addTile(tile_x_start, tile_y_start);
131451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org        }
132451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    }
133451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
134451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
135451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgvoid TiledPictureRenderer::deleteTiles() {
136451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    for (int i = 0; i < fTiles.count(); ++i) {
137451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org        SkDELETE(fTiles[i].fCanvas);
138451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org        SkDELETE(fTiles[i].fBitmap);
139451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    }
140451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
141451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    fTiles.reset();
142451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
143451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
1449d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::drawTiles() {
145163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org    for (int i = 0; i < fTiles.count(); ++i) {
1469d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        fTiles[i].fCanvas->drawPicture(*(fPicture));
147163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org    }
148163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org}
149163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org
1509d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::copyTilesToCanvas() {
151451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    int tile_index = 0;
1529d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org    for (int tile_y_start = 0; tile_y_start < fPicture->height();
153451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org         tile_y_start += fTileHeight) {
1549d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org        for (int tile_x_start = 0; tile_x_start < fPicture->width();
155451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org             tile_x_start += fTileWidth) {
156451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org            SkASSERT(tile_index < fTiles.count());
157451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org            SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
1589d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org            fCanvas->drawBitmap(source,
1599d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org                                SkIntToScalar(tile_x_start),
1609d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org                                SkIntToScalar(tile_y_start));
161451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org            ++tile_index;
162451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org        }
163451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org    }
164451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
165451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org
166451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}
167