blob: e9e14de923262f4042a2526d8952e9dba707039e [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
12#include "gl/GrGLInterface.h"
13#include "GrContext.h"
14#include "SkGpuDevice.h"
15#include "GrContextFactory.h"
16#endif
17
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000018namespace sk_tools {
19
20enum {
21 kDefaultTileWidth = 256,
22 kDefaultTileHeight = 256
23};
24
keyar@chromium.org9d696c02012-08-07 17:11:33 +000025void PictureRenderer::init(SkPicture* pict) {
26 SkASSERT(fPicture == NULL);
27 SkASSERT(fCanvas.get() == NULL);
28 if (fPicture != NULL || fCanvas.get() != NULL) {
29 return;
30 }
31
32 SkASSERT(pict != NULL);
33 if (pict == NULL) {
34 return;
35 }
36
37 fPicture = pict;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000038 switch(fDeviceType) {
39 case kBitmap_DeviceType: {
40 SkBitmap bitmap;
41 sk_tools::setup_bitmap(&bitmap, fPicture->width(), fPicture->height());
42 fCanvas.reset(SkNEW_ARGS(SkCanvas, (bitmap)));
43 break;
44 }
45#if SK_SUPPORT_GPU
46 case kGPU_DeviceType: {
47// const GrGLInterface* interface = GrGLCreateNativeInterface();
48// GrContext* context = GrContext::Create(kOpenGL_Shaders_GrEngine,
49// (GrPlatform3DContext) interface);
50 fGLContext = new SkNativeGLContext();
51 SkASSERT(fGLContext->init(pict->width(), pict->height()));
52 GrContextFactory factory;
53 GrContext* context = factory.get(GrContextFactory::kNative_GLContextType);
54 SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice,
55 (context, SkBitmap::kARGB_8888_Config,
56 pict->width(), pict->height())));
57 fCanvas.reset(SkNEW_ARGS(SkCanvas, (device.get())));
58 break;
59 }
60#endif
61 default:
62 SkASSERT(0);
63 }
keyar@chromium.org9d696c02012-08-07 17:11:33 +000064}
65
66void PictureRenderer::end() {
67 fPicture = NULL;
68 fCanvas.reset(NULL);
69}
70
71void PipePictureRenderer::render() {
72 SkASSERT(fCanvas.get() != NULL);
73 SkASSERT(fPicture != NULL);
74 if (fCanvas.get() == NULL || fPicture == NULL) {
75 return;
76 }
77
78 PipeController pipeController(fCanvas.get());
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000079 SkGPipeWriter writer;
80 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
keyar@chromium.org9d696c02012-08-07 17:11:33 +000081 pipeCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000082 writer.endRecording();
83}
84
keyar@chromium.org9d696c02012-08-07 17:11:33 +000085void SimplePictureRenderer::render() {
86 SkASSERT(fCanvas.get() != NULL);
87 SkASSERT(fPicture != NULL);
88 if (fCanvas.get() == NULL || fPicture == NULL) {
89 return;
90 }
91
92 fCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000093}
94
95TiledPictureRenderer::TiledPictureRenderer()
96 : fTileWidth(kDefaultTileWidth)
97 , fTileHeight(kDefaultTileHeight) {}
98
keyar@chromium.org9d696c02012-08-07 17:11:33 +000099void TiledPictureRenderer::init(SkPicture* pict) {
100 SkASSERT(pict != NULL);
101 SkASSERT(fTiles.count() == 0);
102 if (pict == NULL || fTiles.count() != 0) {
103 return;
104 }
105
106 this->INHERITED::init(pict);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000107
108 if (fTileWidthPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000109 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000110 }
111 if (fTileHeightPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000112 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000113 }
114
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000115 this->setupTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000116}
117
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000118void TiledPictureRenderer::render() {
119 SkASSERT(fCanvas.get() != NULL);
120 SkASSERT(fPicture != NULL);
121 if (fCanvas.get() == NULL || fPicture == NULL) {
122 return;
123 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000124
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000125 this->drawTiles();
126 this->copyTilesToCanvas();
127}
128
129void TiledPictureRenderer::end() {
130 this->deleteTiles();
131 this->INHERITED::end();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000132}
133
134TiledPictureRenderer::~TiledPictureRenderer() {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000135 this->deleteTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000136}
137
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000138void TiledPictureRenderer::clipTile(const TileInfo& tile) {
139 SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
140 SkIntToScalar(fPicture->height()));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000141 tile.fCanvas->clipRect(clip);
142}
143
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000144void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000145 TileInfo* tile = fTiles.push();
146
147 tile->fBitmap = SkNEW(SkBitmap);
148 sk_tools::setup_bitmap(tile->fBitmap, fTileWidth, fTileHeight);
149
150 tile->fCanvas = SkNEW_ARGS(SkCanvas, (*(tile->fBitmap)));
151 tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000152 this->clipTile(*tile);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000153}
154
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000155void TiledPictureRenderer::setupTiles() {
156 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000157 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000158 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000159 tile_x_start += fTileWidth) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000160 this->addTile(tile_x_start, tile_y_start);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000161 }
162 }
163}
164
165void TiledPictureRenderer::deleteTiles() {
166 for (int i = 0; i < fTiles.count(); ++i) {
167 SkDELETE(fTiles[i].fCanvas);
168 SkDELETE(fTiles[i].fBitmap);
169 }
170
171 fTiles.reset();
172}
173
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000174void TiledPictureRenderer::drawTiles() {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000175 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000176 fTiles[i].fCanvas->drawPicture(*(fPicture));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000177 }
178}
179
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000180void TiledPictureRenderer::copyTilesToCanvas() {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000181 int tile_index = 0;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000182 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000183 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000184 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000185 tile_x_start += fTileWidth) {
186 SkASSERT(tile_index < fTiles.count());
187 SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000188 fCanvas->drawBitmap(source,
189 SkIntToScalar(tile_x_start),
190 SkIntToScalar(tile_y_start));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000191 ++tile_index;
192 }
193 }
194}
195
196}