skia2/tools/PictureRenderer.cpp
keyar@chromium.org 9d696c0d04 Refactored the bitmap creation into PictureRenderer.
Further, the picture is also stored in the PictureRenderer.

The main gain of all of this is that we will not have to change how the device in more than one place when we end up adding different devices.

Review URL: https://codereview.appspot.com/6458074

git-svn-id: http://skia.googlecode.com/svn/trunk@4990 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-08-07 17:11:33 +00:00

167 lines
4.3 KiB
C++

#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 PictureRenderer::init(SkPicture* pict) {
SkASSERT(fPicture == NULL);
SkASSERT(fCanvas.get() == NULL);
if (fPicture != NULL || fCanvas.get() != NULL) {
return;
}
SkASSERT(pict != NULL);
if (pict == NULL) {
return;
}
fPicture = pict;
SkBitmap bitmap;
sk_tools::setup_bitmap(&bitmap, fPicture->width(), fPicture->height());
fCanvas.reset(SkNEW_ARGS(SkCanvas, (bitmap)));
}
void PictureRenderer::end() {
fPicture = NULL;
fCanvas.reset(NULL);
}
void PipePictureRenderer::render() {
SkASSERT(fCanvas.get() != NULL);
SkASSERT(fPicture != NULL);
if (fCanvas.get() == NULL || fPicture == NULL) {
return;
}
PipeController pipeController(fCanvas.get());
SkGPipeWriter writer;
SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
pipeCanvas->drawPicture(*fPicture);
writer.endRecording();
}
void SimplePictureRenderer::render() {
SkASSERT(fCanvas.get() != NULL);
SkASSERT(fPicture != NULL);
if (fCanvas.get() == NULL || fPicture == NULL) {
return;
}
fCanvas->drawPicture(*fPicture);
}
TiledPictureRenderer::TiledPictureRenderer()
: fTileWidth(kDefaultTileWidth)
, fTileHeight(kDefaultTileHeight) {}
void TiledPictureRenderer::init(SkPicture* pict) {
SkASSERT(pict != NULL);
SkASSERT(fTiles.count() == 0);
if (pict == NULL || fTiles.count() != 0) {
return;
}
this->INHERITED::init(pict);
if (fTileWidthPercentage > 0) {
fTileWidth = sk_float_ceil2int(fTileWidthPercentage * fPicture->width() / 100);
}
if (fTileHeightPercentage > 0) {
fTileHeight = sk_float_ceil2int(fTileHeightPercentage * fPicture->height() / 100);
}
this->setupTiles();
}
void TiledPictureRenderer::render() {
SkASSERT(fCanvas.get() != NULL);
SkASSERT(fPicture != NULL);
if (fCanvas.get() == NULL || fPicture == NULL) {
return;
}
this->drawTiles();
this->copyTilesToCanvas();
}
void TiledPictureRenderer::end() {
this->deleteTiles();
this->INHERITED::end();
}
TiledPictureRenderer::~TiledPictureRenderer() {
this->deleteTiles();
}
void TiledPictureRenderer::clipTile(const TileInfo& tile) {
SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
SkIntToScalar(fPicture->height()));
tile.fCanvas->clipRect(clip);
}
void TiledPictureRenderer::addTile(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));
this->clipTile(*tile);
}
void TiledPictureRenderer::setupTiles() {
for (int tile_y_start = 0; tile_y_start < fPicture->height();
tile_y_start += fTileHeight) {
for (int tile_x_start = 0; tile_x_start < fPicture->width();
tile_x_start += fTileWidth) {
this->addTile(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::drawTiles() {
for (int i = 0; i < fTiles.count(); ++i) {
fTiles[i].fCanvas->drawPicture(*(fPicture));
}
}
void TiledPictureRenderer::copyTilesToCanvas() {
int tile_index = 0;
for (int tile_y_start = 0; tile_y_start < fPicture->height();
tile_y_start += fTileHeight) {
for (int tile_x_start = 0; tile_x_start < fPicture->width();
tile_x_start += fTileWidth) {
SkASSERT(tile_index < fTiles.count());
SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
fCanvas->drawBitmap(source,
SkIntToScalar(tile_x_start),
SkIntToScalar(tile_y_start));
++tile_index;
}
}
}
}