PictureRenderer.cpp revision a40c20df0e4c5d04acb0841d70127778c0a779ec
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 "SkGpuDevice.h" 13#endif 14 15namespace sk_tools { 16 17enum { 18 kDefaultTileWidth = 256, 19 kDefaultTileHeight = 256 20}; 21 22void PictureRenderer::init(SkPicture* pict) { 23 SkASSERT(NULL == fPicture); 24 SkASSERT(NULL == fCanvas.get()); 25 if (fPicture != NULL || NULL != fCanvas.get()) { 26 return; 27 } 28 29 SkASSERT(pict != NULL); 30 if (NULL == pict) { 31 return; 32 } 33 34 fPicture = pict; 35 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) { 43 switch(fDeviceType) { 44 case kBitmap_DeviceType: { 45 SkBitmap bitmap; 46 sk_tools::setup_bitmap(&bitmap, width, height); 47 return SkNEW_ARGS(SkCanvas, (bitmap)); 48 break; 49 } 50#if SK_SUPPORT_GPU 51 case kGPU_DeviceType: { 52 SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice, 53 (fGrContext, SkBitmap::kARGB_8888_Config, 54 width, height))); 55 return SkNEW_ARGS(SkCanvas, (device.get())); 56 break; 57 } 58#endif 59 default: 60 SkASSERT(0); 61 } 62 63 return NULL; 64} 65 66void PictureRenderer::end() { 67 this->resetState(); 68 fPicture = NULL; 69 fCanvas.reset(NULL); 70} 71 72void PictureRenderer::resetState() { 73 SkASSERT(fCanvas.get() != NULL); 74 SkASSERT(fPicture != NULL); 75 if (NULL == fCanvas.get() || NULL == fPicture) { 76 return; 77 } 78 79 fCanvas->flush(); 80 81#if SK_SUPPORT_GPU 82 if (this->isUsingGpuDevice()) { 83 SkGLContext* glContext = fGrContextFactory.getGLContext( 84 GrContextFactory::kNative_GLContextType); 85 SK_GL(*glContext, Finish()); 86 fGrContext->freeGpuResources(); 87 } 88#endif 89} 90 91void PipePictureRenderer::render() { 92 SkASSERT(fCanvas.get() != NULL); 93 SkASSERT(fPicture != NULL); 94 if (NULL == fCanvas.get() || NULL == fPicture) { 95 return; 96 } 97 98 PipeController pipeController(fCanvas.get()); 99 SkGPipeWriter writer; 100 SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 101 pipeCanvas->drawPicture(*fPicture); 102 writer.endRecording(); 103} 104 105void SimplePictureRenderer::render() { 106 SkASSERT(fCanvas.get() != NULL); 107 SkASSERT(fPicture != NULL); 108 if (NULL == fCanvas.get() || NULL == fPicture) { 109 return; 110 } 111 112 fCanvas->drawPicture(*fPicture); 113} 114 115TiledPictureRenderer::TiledPictureRenderer() 116 : fTileWidth(kDefaultTileWidth) 117 , fTileHeight(kDefaultTileHeight) {} 118 119void TiledPictureRenderer::init(SkPicture* pict) { 120 SkASSERT(pict != NULL); 121 SkASSERT(0 == fTiles.count()); 122 if (NULL == pict || fTiles.count() != 0) { 123 return; 124 } 125 126 this->INHERITED::init(pict); 127 128 if (fTileWidthPercentage > 0) { 129 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100)); 130 } 131 if (fTileHeightPercentage > 0) { 132 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100)); 133 } 134 135 this->setupTiles(); 136} 137 138void TiledPictureRenderer::render() { 139 SkASSERT(fCanvas.get() != NULL); 140 SkASSERT(fPicture != NULL); 141 if (NULL == fCanvas.get() || NULL == fPicture) { 142 return; 143 } 144 145 this->drawTiles(); 146 this->copyTilesToCanvas(); 147} 148 149void TiledPictureRenderer::end() { 150 this->deleteTiles(); 151 this->INHERITED::end(); 152} 153 154TiledPictureRenderer::~TiledPictureRenderer() { 155 this->deleteTiles(); 156} 157 158void TiledPictureRenderer::clipTile(const TileInfo& tile) { 159 SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()), 160 SkIntToScalar(fPicture->height())); 161 tile.fCanvas->clipRect(clip); 162} 163 164void TiledPictureRenderer::addTile(int tile_x_start, int tile_y_start) { 165 TileInfo* tile = fTiles.push(); 166 167 tile->fCanvas = this->setupCanvas(fTileWidth, fTileHeight); 168 tile->fCanvas->translate(SkIntToScalar(-tile_x_start), SkIntToScalar(-tile_y_start)); 169 this->clipTile(*tile); 170} 171 172void TiledPictureRenderer::setupTiles() { 173 for (int tile_y_start = 0; tile_y_start < fPicture->height(); 174 tile_y_start += fTileHeight) { 175 for (int tile_x_start = 0; tile_x_start < fPicture->width(); 176 tile_x_start += fTileWidth) { 177 this->addTile(tile_x_start, tile_y_start); 178 } 179 } 180} 181 182void TiledPictureRenderer::deleteTiles() { 183 for (int i = 0; i < fTiles.count(); ++i) { 184 SkDELETE(fTiles[i].fCanvas); 185 } 186 187 fTiles.reset(); 188} 189 190void TiledPictureRenderer::drawTiles() { 191 for (int i = 0; i < fTiles.count(); ++i) { 192 fTiles[i].fCanvas->drawPicture(*(fPicture)); 193 } 194} 195 196void TiledPictureRenderer::resetState() { 197 SkASSERT(fCanvas.get() != NULL); 198 SkASSERT(fPicture != NULL); 199 if (NULL == fCanvas.get() || NULL == fPicture) { 200 return; 201 } 202 203 for (int i = 0; i < fTiles.count(); ++i) { 204 fTiles[i].fCanvas->flush(); 205 } 206 207 this->INHERITED::resetState(); 208} 209 210void TiledPictureRenderer::copyTilesToCanvas() { 211 int tile_index = 0; 212 for (int tile_y_start = 0; tile_y_start < fPicture->height(); 213 tile_y_start += fTileHeight) { 214 for (int tile_x_start = 0; tile_x_start < fPicture->width(); 215 tile_x_start += fTileWidth) { 216 SkASSERT(tile_index < fTiles.count()); 217 SkBitmap source = fTiles[tile_index].fCanvas->getDevice()->accessBitmap(false); 218 fCanvas->drawBitmap(source, 219 SkIntToScalar(tile_x_start), 220 SkIntToScalar(tile_y_start)); 221 ++tile_index; 222 } 223 } 224} 225 226} 227