blob: 84e7f85db31334824f6eaa2885b3e7bffbc18c40 [file] [log] [blame]
keyar@chromium.org451bb9f2012-07-26 17:27:57 +00001#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
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000011#if SK_SUPPORT_GPU
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000012#include "SkGpuDevice.h"
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000013#endif
14
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000015namespace sk_tools {
16
17enum {
18 kDefaultTileWidth = 256,
19 kDefaultTileHeight = 256
20};
21
keyar@chromium.org9d696c02012-08-07 17:11:33 +000022void PictureRenderer::init(SkPicture* pict) {
keyar@chromium.org78a35c52012-08-20 15:03:44 +000023 SkASSERT(NULL == fPicture);
24 SkASSERT(NULL == fCanvas.get());
25 if (fPicture != NULL || NULL != fCanvas.get()) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000026 return;
27 }
28
29 SkASSERT(pict != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +000030 if (NULL == pict) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000031 return;
32 }
33
34 fPicture = pict;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000035 switch(fDeviceType) {
36 case kBitmap_DeviceType: {
37 SkBitmap bitmap;
38 sk_tools::setup_bitmap(&bitmap, fPicture->width(), fPicture->height());
39 fCanvas.reset(SkNEW_ARGS(SkCanvas, (bitmap)));
40 break;
41 }
42#if SK_SUPPORT_GPU
43 case kGPU_DeviceType: {
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000044 SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice,
keyar@chromium.org06125642012-08-20 15:03:33 +000045 (fGrContext, SkBitmap::kARGB_8888_Config,
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000046 pict->width(), pict->height())));
47 fCanvas.reset(SkNEW_ARGS(SkCanvas, (device.get())));
48 break;
49 }
50#endif
51 default:
52 SkASSERT(0);
53 }
keyar@chromium.org9d696c02012-08-07 17:11:33 +000054}
55
56void PictureRenderer::end() {
keyar@chromium.org77a55222012-08-20 15:03:47 +000057 this->resetState();
keyar@chromium.org9d696c02012-08-07 17:11:33 +000058 fPicture = NULL;
59 fCanvas.reset(NULL);
60}
61
keyar@chromium.org77a55222012-08-20 15:03:47 +000062void PictureRenderer::resetState() {
63 fCanvas->flush();
64
65 if (this->isUsingGpuDevice()) {
66 SkGLContext* glContext = fGrContextFactory.getGLContext(
67 GrContextFactory::kNative_GLContextType);
68 SK_GL(*glContext, Finish());
69 fGrContext->freeGpuResources();
70 }
71}
72
keyar@chromium.org9d696c02012-08-07 17:11:33 +000073void PipePictureRenderer::render() {
74 SkASSERT(fCanvas.get() != NULL);
75 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +000076 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000077 return;
78 }
79
80 PipeController pipeController(fCanvas.get());
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000081 SkGPipeWriter writer;
82 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
keyar@chromium.org9d696c02012-08-07 17:11:33 +000083 pipeCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000084 writer.endRecording();
85}
86
keyar@chromium.org9d696c02012-08-07 17:11:33 +000087void SimplePictureRenderer::render() {
88 SkASSERT(fCanvas.get() != NULL);
89 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +000090 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000091 return;
92 }
93
94 fCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000095}
96
97TiledPictureRenderer::TiledPictureRenderer()
98 : fTileWidth(kDefaultTileWidth)
99 , fTileHeight(kDefaultTileHeight) {}
100
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000101void TiledPictureRenderer::init(SkPicture* pict) {
102 SkASSERT(pict != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000103 SkASSERT(0 == fTiles.count());
104 if (NULL == pict || fTiles.count() != 0) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000105 return;
106 }
107
108 this->INHERITED::init(pict);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000109
110 if (fTileWidthPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000111 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000112 }
113 if (fTileHeightPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000114 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000115 }
116
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000117 this->setupTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000118}
119
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000120void TiledPictureRenderer::render() {
121 SkASSERT(fCanvas.get() != NULL);
122 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000123 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000124 return;
125 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000126
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000127 this->drawTiles();
128 this->copyTilesToCanvas();
129}
130
131void TiledPictureRenderer::end() {
132 this->deleteTiles();
133 this->INHERITED::end();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000134}
135
136TiledPictureRenderer::~TiledPictureRenderer() {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000137 this->deleteTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000138}
139
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000140void TiledPictureRenderer::clipTile(const TileInfo& tile) {
141 SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
142 SkIntToScalar(fPicture->height()));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000143 tile.fCanvas->clipRect(clip);
144}
145
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000146void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000147 TileInfo* tile = fTiles.push();
148
149 tile->fBitmap = SkNEW(SkBitmap);
150 sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight);
151
152 tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap)));
153 tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000154 this->clipTile(*tile);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000155}
156
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000157void TiledPictureRenderer::setupTiles() {
158 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000159 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000160 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000161 tile_x_start += fTileWidth) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000162 this->addTile(tile_x_start, tile_y_start);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000163 }
164 }
165}
166
167void TiledPictureRenderer::deleteTiles() {
168 for (int i = 0; i < fTiles.count(); ++i) {
169 SkDELETE(fTiles[i].fCanvas);
170 SkDELETE(fTiles[i].fBitmap);
171 }
172
173 fTiles.reset();
174}
175
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000176void TiledPictureRenderer::drawTiles() {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000177 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000178 fTiles[i].fCanvas->drawPicture(*(fPicture));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000179 }
180}
181
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000182void TiledPictureRenderer::copyTilesToCanvas() {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000183 int tile_index = 0;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000184 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000185 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000186 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000187 tile_x_start += fTileWidth) {
188 SkASSERT(tile_index < fTiles.count());
189 SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000190 fCanvas->drawBitmap(source,
191 SkIntToScalar(tile_x_start),
192 SkIntToScalar(tile_y_start));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000193 ++tile_index;
194 }
195 }
196}
197
198}