PictureRenderer.cpp revision 4ea96c5e5449248780acfeb3cef4ec812f955d74
1#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
11#if SK_SUPPORT_GPU
12#include "gl/GrGLInterface.h"
13#include "GrContext.h"
14#include "SkGpuDevice.h"
15#include "GrContextFactory.h"
16#endif
17
18namespace sk_tools {
19
20enum {
21    kDefaultTileWidth = 256,
22    kDefaultTileHeight = 256
23};
24
25void 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;
38    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    }
64}
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());
79    SkGPipeWriter writer;
80    SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
81    pipeCanvas->drawPicture(*fPicture);
82    writer.endRecording();
83}
84
85void 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);
93}
94
95TiledPictureRenderer::TiledPictureRenderer()
96    : fTileWidth(kDefaultTileWidth)
97    , fTileHeight(kDefaultTileHeight) {}
98
99void 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);
107
108    if (fTileWidthPercentage > 0) {
109        fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
110    }
111    if (fTileHeightPercentage > 0) {
112        fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
113    }
114
115    this->setupTiles();
116}
117
118void TiledPictureRenderer::render() {
119    SkASSERT(fCanvas.get() != NULL);
120    SkASSERT(fPicture != NULL);
121    if (fCanvas.get() == NULL || fPicture == NULL) {
122        return;
123    }
124
125    this->drawTiles();
126    this->copyTilesToCanvas();
127}
128
129void TiledPictureRenderer::end() {
130    this->deleteTiles();
131    this->INHERITED::end();
132}
133
134TiledPictureRenderer::~TiledPictureRenderer() {
135    this->deleteTiles();
136}
137
138void TiledPictureRenderer::clipTile(const TileInfo& tile) {
139    SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
140                                 SkIntToScalar(fPicture->height()));
141    tile.fCanvas->clipRect(clip);
142}
143
144void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
145    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));
152    this->clipTile(*tile);
153}
154
155void TiledPictureRenderer::setupTiles() {
156    for (int tile_y_start = 0; tile_y_start < fPicture->height();
157         tile_y_start += fTileHeight) {
158        for (int tile_x_start = 0; tile_x_start < fPicture->width();
159             tile_x_start += fTileWidth) {
160            this->addTile(tile_x_start, tile_y_start);
161        }
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
174void TiledPictureRenderer::drawTiles() {
175    for (int i = 0; i < fTiles.count(); ++i) {
176        fTiles[i].fCanvas->drawPicture(*(fPicture));
177    }
178}
179
180void TiledPictureRenderer::copyTilesToCanvas() {
181    int tile_index = 0;
182    for (int tile_y_start = 0; tile_y_start < fPicture->height();
183         tile_y_start += fTileHeight) {
184        for (int tile_x_start = 0; tile_x_start < fPicture->width();
185             tile_x_start += fTileWidth) {
186            SkASSERT(tile_index < fTiles.count());
187            SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false);
188            fCanvas->drawBitmap(source,
189                                SkIntToScalar(tile_x_start),
190                                SkIntToScalar(tile_y_start));
191            ++tile_index;
192        }
193    }
194}
195
196}
197