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