blob: 290c79a5fea8357b62f37ae3854534c57b5d6c08 [file] [log] [blame]
keyar@chromium.orgb3fb7c12012-08-20 21:02:49 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
keyar@chromium.org451bb9f2012-07-26 17:27:57 +00008#include "PictureRenderer.h"
9#include "SamplePipeControllers.h"
10#include "SkCanvas.h"
11#include "SkDevice.h"
12#include "SkGPipe.h"
13#include "SkPicture.h"
14#include "SkTDArray.h"
15#include "SkTypes.h"
16#include "picture_utils.h"
17
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000018#if SK_SUPPORT_GPU
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000019#include "SkGpuDevice.h"
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000020#endif
21
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000022namespace sk_tools {
23
24enum {
25 kDefaultTileWidth = 256,
26 kDefaultTileHeight = 256
27};
28
keyar@chromium.org9d696c02012-08-07 17:11:33 +000029void PictureRenderer::init(SkPicture* pict) {
keyar@chromium.org78a35c52012-08-20 15:03:44 +000030 SkASSERT(NULL == fPicture);
31 SkASSERT(NULL == fCanvas.get());
32 if (fPicture != NULL || NULL != fCanvas.get()) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000033 return;
34 }
35
36 SkASSERT(pict != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +000037 if (NULL == pict) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000038 return;
39 }
40
41 fPicture = pict;
keyar@chromium.orga474ce32012-08-20 15:03:57 +000042 fCanvas.reset(this->setupCanvas());
43}
44
45SkCanvas* PictureRenderer::setupCanvas() {
46 return this->setupCanvas(fPicture->width(), fPicture->height());
47}
48
49SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000050 switch(fDeviceType) {
51 case kBitmap_DeviceType: {
52 SkBitmap bitmap;
keyar@chromium.orga474ce32012-08-20 15:03:57 +000053 sk_tools::setup_bitmap(&bitmap, width, height);
54 return SkNEW_ARGS(SkCanvas, (bitmap));
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000055 break;
56 }
57#if SK_SUPPORT_GPU
58 case kGPU_DeviceType: {
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000059 SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice,
keyar@chromium.org06125642012-08-20 15:03:33 +000060 (fGrContext, SkBitmap::kARGB_8888_Config,
keyar@chromium.orga474ce32012-08-20 15:03:57 +000061 width, height)));
62 return SkNEW_ARGS(SkCanvas, (device.get()));
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000063 break;
64 }
65#endif
66 default:
67 SkASSERT(0);
68 }
keyar@chromium.orga474ce32012-08-20 15:03:57 +000069
70 return NULL;
keyar@chromium.org9d696c02012-08-07 17:11:33 +000071}
72
73void PictureRenderer::end() {
keyar@chromium.org77a55222012-08-20 15:03:47 +000074 this->resetState();
keyar@chromium.org9d696c02012-08-07 17:11:33 +000075 fPicture = NULL;
76 fCanvas.reset(NULL);
77}
78
keyar@chromium.org77a55222012-08-20 15:03:47 +000079void PictureRenderer::resetState() {
keyar@chromium.org28136b32012-08-20 15:04:15 +000080#if SK_SUPPORT_GPU
81 if (this->isUsingGpuDevice()) {
82 SkGLContext* glContext = fGrContextFactory.getGLContext(
83 GrContextFactory::kNative_GLContextType);
84 SK_GL(*glContext, Finish());
85 }
86#endif
87}
88
89void PictureRenderer::finishDraw() {
keyar@chromium.orgbffacc02012-08-20 15:04:07 +000090 SkASSERT(fCanvas.get() != NULL);
keyar@chromium.org28136b32012-08-20 15:04:15 +000091 if (NULL == fCanvas.get()) {
keyar@chromium.orgbffacc02012-08-20 15:04:07 +000092 return;
93 }
94
keyar@chromium.org77a55222012-08-20 15:03:47 +000095 fCanvas->flush();
96
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000097#if SK_SUPPORT_GPU
keyar@chromium.org77a55222012-08-20 15:03:47 +000098 if (this->isUsingGpuDevice()) {
99 SkGLContext* glContext = fGrContextFactory.getGLContext(
100 GrContextFactory::kNative_GLContextType);
keyar@chromium.org28136b32012-08-20 15:04:15 +0000101
102 SkASSERT(glContext != NULL);
103 if (NULL == glContext) {
104 return;
105 }
106
keyar@chromium.org77a55222012-08-20 15:03:47 +0000107 SK_GL(*glContext, Finish());
keyar@chromium.org77a55222012-08-20 15:03:47 +0000108 }
keyar@chromium.orga40c20d2012-08-20 15:04:12 +0000109#endif
keyar@chromium.org77a55222012-08-20 15:03:47 +0000110}
111
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000112void PipePictureRenderer::render() {
113 SkASSERT(fCanvas.get() != NULL);
114 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000115 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000116 return;
117 }
118
119 PipeController pipeController(fCanvas.get());
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000120 SkGPipeWriter writer;
121 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000122 pipeCanvas->drawPicture(*fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000123 writer.endRecording();
keyar@chromium.org28136b32012-08-20 15:04:15 +0000124 this->finishDraw();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000125}
126
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000127void SimplePictureRenderer::render() {
128 SkASSERT(fCanvas.get() != NULL);
129 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000130 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000131 return;
132 }
133
134 fCanvas->drawPicture(*fPicture);
keyar@chromium.org28136b32012-08-20 15:04:15 +0000135 this->finishDraw();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000136}
137
138TiledPictureRenderer::TiledPictureRenderer()
139 : fTileWidth(kDefaultTileWidth)
140 , fTileHeight(kDefaultTileHeight) {}
141
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000142void TiledPictureRenderer::init(SkPicture* pict) {
143 SkASSERT(pict != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000144 SkASSERT(0 == fTiles.count());
145 if (NULL == pict || fTiles.count() != 0) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000146 return;
147 }
148
149 this->INHERITED::init(pict);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000150
151 if (fTileWidthPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000152 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000153 }
154 if (fTileHeightPercentage > 0) {
robertphillips@google.com5d8d1862012-08-15 14:36:41 +0000155 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000156 }
157
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000158 this->setupTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000159}
160
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000161void TiledPictureRenderer::render() {
162 SkASSERT(fCanvas.get() != NULL);
163 SkASSERT(fPicture != NULL);
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000164 if (NULL == fCanvas.get() || NULL == fPicture) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000165 return;
166 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000167
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000168 this->drawTiles();
169 this->copyTilesToCanvas();
keyar@chromium.org28136b32012-08-20 15:04:15 +0000170 this->finishDraw();
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000171}
172
173void TiledPictureRenderer::end() {
174 this->deleteTiles();
175 this->INHERITED::end();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000176}
177
178TiledPictureRenderer::~TiledPictureRenderer() {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000179 this->deleteTiles();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000180}
181
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000182void TiledPictureRenderer::clipTile(SkCanvas* tile) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000183 SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
184 SkIntToScalar(fPicture->height()));
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000185 tile->clipRect(clip);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000186}
187
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000188void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) {
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000189 SkCanvas* tile = this->setupCanvas(fTileWidth, fTileHeight);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000190
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000191 tile->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start));
192 this->clipTile(tile);
193
194 fTiles.push(tile);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000195}
196
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000197void TiledPictureRenderer::setupTiles() {
198 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000199 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000200 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000201 tile_x_start += fTileWidth) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000202 this->addTile(tile_x_start, tile_y_start);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000203 }
204 }
205}
206
207void TiledPictureRenderer::deleteTiles() {
208 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000209 SkDELETE(fTiles[i]);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000210 }
211
212 fTiles.reset();
213}
214
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000215void TiledPictureRenderer::drawTiles() {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000216 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000217 fTiles[i]->drawPicture(*(fPicture));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000218 }
219}
220
keyar@chromium.org28136b32012-08-20 15:04:15 +0000221void TiledPictureRenderer::finishDraw() {
keyar@chromium.org275be532012-08-20 15:04:00 +0000222 for (int i = 0; i < fTiles.count(); ++i) {
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000223 fTiles[i]->flush();
keyar@chromium.org275be532012-08-20 15:04:00 +0000224 }
225
keyar@chromium.org28136b32012-08-20 15:04:15 +0000226#if SK_SUPPORT_GPU
227 if (this->isUsingGpuDevice()) {
228 SkGLContext* glContext = fGrContextFactory.getGLContext(
229 GrContextFactory::kNative_GLContextType);
230
231 SkASSERT(glContext != NULL);
232 if (NULL == glContext) {
233 return;
234 }
235
236 SK_GL(*glContext, Finish());
237 }
238#endif
keyar@chromium.org275be532012-08-20 15:04:00 +0000239}
240
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000241void TiledPictureRenderer::copyTilesToCanvas() {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000242 int tile_index = 0;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000243 for (int tile_y_start = 0; tile_y_start < fPicture->height();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000244 tile_y_start += fTileHeight) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000245 for (int tile_x_start = 0; tile_x_start < fPicture->width();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000246 tile_x_start += fTileWidth) {
247 SkASSERT(tile_index < fTiles.count());
keyar@chromium.orgda652c22012-08-20 22:04:07 +0000248 SkBitmap source = fTiles[tile_index]->getDevice()->accessBitmap(false);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000249 fCanvas->drawBitmap(source,
250 SkIntToScalar(tile_x_start),
251 SkIntToScalar(tile_y_start));
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000252 ++tile_index;
253 }
254 }
255}
256
257}