blob: bae8a4bb40c88565d86995b755ca5c9497c2d614 [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.orga474ce32012-08-20 15:03:57 +000035 fCanvas.reset(this->setupCanvas());
36}
37
38SkCanvas* PictureRenderer::setupCanvas() {
39 return this->setupCanvas(fPicture->width(), fPicture->height());
40}
41
42SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000043 switch(fDeviceType) {
44 case kBitmap_DeviceType: {
45 SkBitmap bitmap;
keyar@chromium.orga474ce32012-08-20 15:03:57 +000046 sk_tools::setup_bitmap(&bitmap, width, height);
47 return SkNEW_ARGS(SkCanvas, (bitmap));
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000048 break;
49 }
50#if SK_SUPPORT_GPU
51 case kGPU_DeviceType: {
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000052 SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice,
keyar@chromium.org06125642012-08-20 15:03:33 +000053 (fGrContext, SkBitmap::kARGB_8888_Config,
keyar@chromium.orga474ce32012-08-20 15:03:57 +000054 width, height)));
55 return SkNEW_ARGS(SkCanvas, (device.get()));
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000056 break;
57 }
58#endif
59 default:
60 SkASSERT(0);
61 }
keyar@chromium.orga474ce32012-08-20 15:03:57 +000062
63 return NULL;
keyar@chromium.org9d696c02012-08-07 17:11:33 +000064}
65
66void PictureRenderer::end() {
keyar@chromium.org77a55222012-08-20 15:03:47 +000067 this->resetState();
keyar@chromium.org9d696c02012-08-07 17:11:33 +000068 fPicture = NULL;
69 fCanvas.reset(NULL);
70}
71
keyar@chromium.org77a55222012-08-20 15:03:47 +000072void PictureRenderer::resetState() {
keyar@chromium.org28136b32012-08-20 15:04:15 +000073#if SK_SUPPORT_GPU
74 if (this->isUsingGpuDevice()) {
75 SkGLContext* glContext = fGrContextFactory.getGLContext(
76 GrContextFactory::kNative_GLContextType);
77 SK_GL(*glContext, Finish());
78 }
79#endif
80}
81
82void PictureRenderer::finishDraw() {
keyar@chromium.orgbffacc02012-08-20 15:04:07 +000083 SkASSERT(fCanvas.get() != NULL);
keyar@chromium.org28136b32012-08-20 15:04:15 +000084 if (NULL == fCanvas.get()) {
keyar@chromium.orgbffacc02012-08-20 15:04:07 +000085 return;
86 }
87
keyar@chromium.org77a55222012-08-20 15:03:47 +000088 fCanvas->flush();
89
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000090#if SK_SUPPORT_GPU
keyar@chromium.org77a55222012-08-20 15:03:47 +000091 if (this->isUsingGpuDevice()) {
92 SkGLContext* glContext = fGrContextFactory.getGLContext(
93 GrContextFactory::kNative_GLContextType);
keyar@chromium.org28136b32012-08-20 15:04:15 +000094
95 SkASSERT(glContext != NULL);
96 if (NULL == glContext) {
97 return;
98 }
99
keyar@chromium.org77a55222012-08-20 15:03:47 +0000100 SK_GL(*glContext, Finish());
keyar@chromium.org77a55222012-08-20 15:03:47 +0000101 }
keyar@chromium.orga40c20d2012-08-20 15:04:12 +0000102#endif
keyar@chromium.org77a55222012-08-20 15:03:47 +0000103}
104
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000105void PipePictureRenderer::render() {
106 SkASSERT(fCanvas.get() != NULL);
107 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000108 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000109 return;
110 }
111
112 PipeController pipeController(fCanvas.get());
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000113 SkGPipeWriter writer;
114 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000115 pipeCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000116 writer.endRecording();
keyar@chromium.org28136b32012-08-20 15:04:15 +0000117 this->finishDraw();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000118}
119
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000120void SimplePictureRenderer::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 }
126
127 fCanvas->drawPicture(*fPicture);
keyar@chromium.org28136b32012-08-20 15:04:15 +0000128 this->finishDraw();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000129}
130
131TiledPictureRenderer::TiledPictureRenderer()
132 : fTileWidth(kDefaultTileWidth)
133 , fTileHeight(kDefaultTileHeight) {}
134
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000135void TiledPictureRenderer::init(SkPicture* pict) {
136 SkASSERT(pict != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000137 SkASSERT(0 == fTiles.count());
138 if (NULL == pict || fTiles.count() != 0) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000139 return;
140 }
141
142 this->INHERITED::init(pict);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000143
144 if (fTileWidthPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000145 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000146 }
147 if (fTileHeightPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000148 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000149 }
150
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000151 this->setupTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000152}
153
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000154void TiledPictureRenderer::render() {
155 SkASSERT(fCanvas.get() != NULL);
156 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000157 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000158 return;
159 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000160
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000161 this->drawTiles();
162 this->copyTilesToCanvas();
keyar@chromium.org28136b32012-08-20 15:04:15 +0000163 this->finishDraw();
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000164}
165
166void TiledPictureRenderer::end() {
167 this->deleteTiles();
168 this->INHERITED::end();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000169}
170
171TiledPictureRenderer::~TiledPictureRenderer() {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000172 this->deleteTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000173}
174
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000175void TiledPictureRenderer::clipTile(const TileInfo& tile) {
176 SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
177 SkIntToScalar(fPicture->height()));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000178 tile.fCanvas->clipRect(clip);
179}
180
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000181void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000182 TileInfo* tile = fTiles.push();
183
keyar@chromium.orga474ce32012-08-20 15:03:57 +0000184 tile->fCanvas = this->setupCanvas(fTileWidth, fTileHeight);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000185 tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000186 this->clipTile(*tile);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000187}
188
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000189void TiledPictureRenderer::setupTiles() {
190 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000191 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000192 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000193 tile_x_start += fTileWidth) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000194 this->addTile(tile_x_start, tile_y_start);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000195 }
196 }
197}
198
199void TiledPictureRenderer::deleteTiles() {
200 for (int i = 0; i < fTiles.count(); ++i) {
201 SkDELETE(fTiles[i].fCanvas);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000202 }
203
204 fTiles.reset();
205}
206
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000207void TiledPictureRenderer::drawTiles() {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000208 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000209 fTiles[i].fCanvas->drawPicture(*(fPicture));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000210 }
211}
212
keyar@chromium.org28136b32012-08-20 15:04:15 +0000213void TiledPictureRenderer::finishDraw() {
keyar@chromium.org275be532012-08-20 15:04:00 +0000214 for (int i = 0; i < fTiles.count(); ++i) {
215 fTiles[i].fCanvas->flush();
216 }
217
keyar@chromium.org28136b32012-08-20 15:04:15 +0000218#if SK_SUPPORT_GPU
219 if (this->isUsingGpuDevice()) {
220 SkGLContext* glContext = fGrContextFactory.getGLContext(
221 GrContextFactory::kNative_GLContextType);
222
223 SkASSERT(glContext != NULL);
224 if (NULL == glContext) {
225 return;
226 }
227
228 SK_GL(*glContext, Finish());
229 }
230#endif
keyar@chromium.org275be532012-08-20 15:04:00 +0000231}
232
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000233void TiledPictureRenderer::copyTilesToCanvas() {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000234 int tile_index = 0;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000235 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000236 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000237 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000238 tile_x_start += fTileWidth) {
239 SkASSERT(tile_index < fTiles.count());
240 SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000241 fCanvas->drawBitmap(source,
242 SkIntToScalar(tile_x_start),
243 SkIntToScalar(tile_y_start));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000244 ++tile_index;
245 }
246 }
247}
248
249}