PictureRenderer.cpp revision 070d354d51dac52a70f07d4b102392b89f2da5d7
1b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org/* 2b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org * Copyright 2012 Google Inc. 3b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org * 4b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org * Use of this source code is governed by a BSD-style license that can be 5b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org * found in the LICENSE file. 6b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org */ 7b3fb7c1f467c4d43dff0d98683d3043f0176e07ckeyar@chromium.org 8451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "PictureRenderer.h" 958b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "picture_utils.h" 10451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SamplePipeControllers.h" 11451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkCanvas.h" 12451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkDevice.h" 13451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkGPipe.h" 1458b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#if SK_SUPPORT_GPU 1558b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkGpuDevice.h" 1658b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#endif 1758b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkGraphics.h" 1858b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkImageEncoder.h" 19ea82695325e2afc68f646fcc23fcae8b1bff6dc1keyar@chromium.org#include "SkMatrix.h" 20451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkPicture.h" 21ea82695325e2afc68f646fcc23fcae8b1bff6dc1keyar@chromium.org#include "SkScalar.h" 229299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org#include "SkString.h" 2358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkTemplates.h" 24451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTDArray.h" 2558b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkThreadUtils.h" 26451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTypes.h" 274ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org 28451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgnamespace sk_tools { 29451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 30451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgenum { 31451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org kDefaultTileWidth = 256, 32451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org kDefaultTileHeight = 256 33451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}; 34451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 359d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PictureRenderer::init(SkPicture* pict) { 3678a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org SkASSERT(NULL == fPicture); 3778a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org SkASSERT(NULL == fCanvas.get()); 3878a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (fPicture != NULL || NULL != fCanvas.get()) { 399d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 409d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 419d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 429d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(pict != NULL); 4378a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == pict) { 449d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 459d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 469d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 479d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org fPicture = pict; 48a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org fCanvas.reset(this->setupCanvas()); 49a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org} 50a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 51a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.orgSkCanvas* PictureRenderer::setupCanvas() { 52a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org return this->setupCanvas(fPicture->width(), fPicture->height()); 53a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org} 54a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 55a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.orgSkCanvas* PictureRenderer::setupCanvas(int width, int height) { 564ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org switch(fDeviceType) { 574ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org case kBitmap_DeviceType: { 584ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org SkBitmap bitmap; 59a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org sk_tools::setup_bitmap(&bitmap, width, height); 60a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 614ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org break; 624ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 634ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org#if SK_SUPPORT_GPU 644ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org case kGPU_DeviceType: { 654ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org SkAutoTUnref<SkGpuDevice> device(SkNEW_ARGS(SkGpuDevice, 660612564bb76ec533d26d87e03368fd81ef97831ekeyar@chromium.org (fGrContext, SkBitmap::kARGB_8888_Config, 67a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org width, height))); 68a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org return SkNEW_ARGS(SkCanvas, (device.get())); 694ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org break; 704ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 714ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org#endif 724ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org default: 734ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org SkASSERT(0); 744ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 75a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 76a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org return NULL; 779d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org} 789d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 799d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PictureRenderer::end() { 8077a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org this->resetState(); 819d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org fPicture = NULL; 829d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org fCanvas.reset(NULL); 839d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org} 849d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 8577a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.orgvoid PictureRenderer::resetState() { 8628136b308fe467da113983cfee332faea133cd8akeyar@chromium.org#if SK_SUPPORT_GPU 8728136b308fe467da113983cfee332faea133cd8akeyar@chromium.org if (this->isUsingGpuDevice()) { 8828136b308fe467da113983cfee332faea133cd8akeyar@chromium.org SkGLContext* glContext = fGrContextFactory.getGLContext( 8928136b308fe467da113983cfee332faea133cd8akeyar@chromium.org GrContextFactory::kNative_GLContextType); 9028136b308fe467da113983cfee332faea133cd8akeyar@chromium.org 9128136b308fe467da113983cfee332faea133cd8akeyar@chromium.org SkASSERT(glContext != NULL); 9228136b308fe467da113983cfee332faea133cd8akeyar@chromium.org if (NULL == glContext) { 9328136b308fe467da113983cfee332faea133cd8akeyar@chromium.org return; 9428136b308fe467da113983cfee332faea133cd8akeyar@chromium.org } 9528136b308fe467da113983cfee332faea133cd8akeyar@chromium.org 969a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fGrContext->flush(); 9777a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org SK_GL(*glContext, Finish()); 9877a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org } 99a40c20df0e4c5d04acb0841d70127778c0a779eckeyar@chromium.org#endif 10077a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org} 10177a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org 102b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com/** 103b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * Write the canvas to the specified path. 104b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * @param canvas Must be non-null. Canvas to be written to a file. 105b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * @param path Path for the file to be written. Should have no extension; write() will append 106b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * an appropriate one. Passed in by value so it can be modified. 107b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * @return bool True if the Canvas is written to a file. 108b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com */ 109b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.comstatic bool write(SkCanvas* canvas, SkString path) { 11081f9d2e05be4902993345dac93337158345c660bscroggo@google.com SkASSERT(canvas != NULL); 111b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com if (NULL == canvas) { 1129299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org return false; 1139299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org } 1149299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 1159299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org SkBitmap bitmap; 11681f9d2e05be4902993345dac93337158345c660bscroggo@google.com SkISize size = canvas->getDeviceSize(); 11781f9d2e05be4902993345dac93337158345c660bscroggo@google.com sk_tools::setup_bitmap(&bitmap, size.width(), size.height()); 1189299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 11981f9d2e05be4902993345dac93337158345c660bscroggo@google.com canvas->readPixels(&bitmap, 0, 0); 1209299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org sk_tools::force_all_opaque(bitmap); 1219299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 12281f9d2e05be4902993345dac93337158345c660bscroggo@google.com // Since path is passed in by value, it is okay to modify it. 12381f9d2e05be4902993345dac93337158345c660bscroggo@google.com path.append(".png"); 1249299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org return SkImageEncoder::EncodeFile(path.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100); 1259299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org} 1269299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 127b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com/** 128b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * If path is non NULL, append number to it, and call write(SkCanvas*, SkString) to write the 129b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * provided canvas to a file. Returns true if path is NULL or if write() succeeds. 130b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com */ 131b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.comstatic bool writeAppendNumber(SkCanvas* canvas, const SkString* path, int number) { 132b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com if (NULL == path) { 133b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com return true; 134b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com } 135b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkString pathWithNumber(*path); 136b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com pathWithNumber.appendf("%i", number); 137b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com return write(canvas, pathWithNumber); 138b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com} 139b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com 140acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 141acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 14281f9d2e05be4902993345dac93337158345c660bscroggo@google.combool RecordPictureRenderer::render(const SkString*) { 1439a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com SkPicture replayer; 1449a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com SkCanvas* recorder = replayer.beginRecording(fPicture->width(), fPicture->height()); 1459a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fPicture->draw(recorder); 1469a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com replayer.endRecording(); 14781f9d2e05be4902993345dac93337158345c660bscroggo@google.com // Since this class does not actually render, return false. 14881f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 1499a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com} 1509a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com 151acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 152acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 15381f9d2e05be4902993345dac93337158345c660bscroggo@google.combool PipePictureRenderer::render(const SkString* path) { 1549d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fCanvas.get() != NULL); 1559d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fPicture != NULL); 15678a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == fCanvas.get() || NULL == fPicture) { 15781f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 1589d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 1599d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 1609d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org PipeController pipeController(fCanvas.get()); 161451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org SkGPipeWriter writer; 162451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 1639d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org pipeCanvas->drawPicture(*fPicture); 164451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org writer.endRecording(); 1659a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fCanvas->flush(); 166070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com if (NULL != path) { 167070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com return write(fCanvas, *path); 168070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com } 169070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com return true; 170451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 171451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 172acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 173acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 17481f9d2e05be4902993345dac93337158345c660bscroggo@google.combool SimplePictureRenderer::render(const SkString* path) { 1759d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fCanvas.get() != NULL); 1769d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fPicture != NULL); 17778a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == fCanvas.get() || NULL == fPicture) { 17881f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 1799d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 1809d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 1819d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org fCanvas->drawPicture(*fPicture); 1829a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fCanvas->flush(); 183070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com if (NULL != path) { 184070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com return write(fCanvas, *path); 185070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com } 186070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com return true; 187451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 188451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 189acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 190acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 191451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgTiledPictureRenderer::TiledPictureRenderer() 192bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com : fUsePipe(false) 19358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com , fTileWidth(kDefaultTileWidth) 194b947b91794f47cc92b17c83e570536f5e315a118rileya@google.com , fTileHeight(kDefaultTileHeight) 195a04dc02b118363fedf3a7b11cfcdab886d368f8arileya@google.com , fTileWidthPercentage(0.0) 196b947b91794f47cc92b17c83e570536f5e315a118rileya@google.com , fTileHeightPercentage(0.0) 197bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fTileMinPowerOf2Width(0) 198bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fTileCounter(0) 199bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fNumThreads(1) 200bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fPictureClones(NULL) 201bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fPipeController(NULL) { } 202451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 2039d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::init(SkPicture* pict) { 2049d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(pict != NULL); 205acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkASSERT(0 == fTileRects.count()); 206acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com if (NULL == pict || fTileRects.count() != 0) { 2079d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 2089d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 2099d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 210acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // Do not call INHERITED::init(), which would create a (potentially large) canvas which is not 211acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // used by bench_pictures. 212acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com fPicture = pict; 213cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org 214cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org if (fTileWidthPercentage > 0) { 2155d8d18651a64f62dbb8881794e23f53bf22c9a23robertphillips@google.com fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->width() / 100)); 216cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org } 217cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org if (fTileHeightPercentage > 0) { 2185d8d18651a64f62dbb8881794e23f53bf22c9a23robertphillips@google.com fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture->height() / 100)); 219cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org } 220cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org 221f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org if (fTileMinPowerOf2Width > 0) { 222f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org this->setupPowerOf2Tiles(); 223f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } else { 224f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org this->setupTiles(); 225f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 226bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 227bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (this->multiThreaded()) { 228bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com for (int i = 0; i < fNumThreads; ++i) { 229bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com *fCanvasPool.append() = this->setupCanvas(fTileWidth, fTileHeight); 230bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 231bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (!fUsePipe) { 232bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(NULL == fPictureClones); 233bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Only need to create fNumThreads - 1 clones, since one thread will use the base 234bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // picture. 235bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com int numberOfClones = fNumThreads - 1; 236bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // This will be deleted in end(). 237bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fPictureClones = SkNEW_ARRAY(SkPicture, numberOfClones); 238b4773b4802236fab24cfc63ed8b9ed7eb35f65ccscroggo@google.com fPicture->clone(fPictureClones, numberOfClones); 239bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 240bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 241451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 242451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 2439d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::end() { 244bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fTileRects.reset(); 245bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE_ARRAY(fPictureClones); 246bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fPictureClones = NULL; 247bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fCanvasPool.unrefAll(); 248bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (fPipeController != NULL) { 249bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(fUsePipe); 250bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE(fPipeController); 251bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fPipeController = NULL; 252bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 2539d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org this->INHERITED::end(); 254451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 255451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 256451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgTiledPictureRenderer::~TiledPictureRenderer() { 257bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // end() must be called to delete fPictureClones and fPipeController 258bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(NULL == fPictureClones); 259bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(NULL == fPipeController); 260451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 261451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 2629d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::setupTiles() { 263acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) { 264acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com for (int tile_x_start = 0; tile_x_start < fPicture->width(); tile_x_start += fTileWidth) { 265acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), 266acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(tile_y_start), 267acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileWidth), 268acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileHeight)); 269f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 270f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 271f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org} 272f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 273f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// The goal of the powers of two tiles is to minimize the amount of wasted tile 274f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// space in the width-wise direction and then minimize the number of tiles. The 275f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// constraints are that every tile must have a pixel width that is a power of 276f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// two and also be of some minimal width (that is also a power of two). 277f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// 27858b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com// This is solved by first taking our picture size and rounding it up to the 279f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// multiple of the minimal width. The binary representation of this rounded 280f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// value gives us the tiles we need: a bit of value one means we need a tile of 281f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// that size. 282f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.orgvoid TiledPictureRenderer::setupPowerOf2Tiles() { 283f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int rounded_value = fPicture->width(); 284f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org if (fPicture->width() % fTileMinPowerOf2Width != 0) { 285f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org rounded_value = fPicture->width() - (fPicture->width() % fTileMinPowerOf2Width) 286f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org + fTileMinPowerOf2Width; 287f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 288f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 28994acc70312d8fe6605dea99f27f62b180bf22284robertphillips@google.com int num_bits = SkScalarCeilToInt(SkScalarLog2(SkIntToScalar(fPicture->width()))); 290f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int largest_possible_tile_size = 1 << num_bits; 291f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 292f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org // The tile height is constant for a particular picture. 293f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org for (int tile_y_start = 0; tile_y_start < fPicture->height(); tile_y_start += fTileHeight) { 294f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int tile_x_start = 0; 295f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int current_width = largest_possible_tile_size; 296acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough 297acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // to draw each tile. 298acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com fTileWidth = current_width; 299f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 300f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org while (current_width >= fTileMinPowerOf2Width) { 301f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org // It is very important this is a bitwise AND. 302f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org if (current_width & rounded_value) { 303acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), 304acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(tile_y_start), 305acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(current_width), 306acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileHeight)); 307f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org tile_x_start += current_width; 308f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 309f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 310f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org current_width >>= 1; 311451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org } 312451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org } 313451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 314451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 315bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com/** 316bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * Draw the specified playback to the canvas translated to rectangle provided, so that this mini 317bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * canvas represents the rectangle's portion of the overall picture. 318bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * Saves and restores so that the initial clip and matrix return to their state before this function 319bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * is called. 320bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com */ 321bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comtemplate<class T> 322bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comstatic void DrawTileToCanvas(SkCanvas* canvas, const SkRect& tileRect, T* playback) { 323bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com int saveCount = canvas->save(); 324bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Translate so that we draw the correct portion of the picture 325bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->translate(-tileRect.fLeft, -tileRect.fTop); 326bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com playback->draw(canvas); 327bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->restoreToCount(saveCount); 328bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->flush(); 329451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 330451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 33158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 332bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com// Base class for data used both by pipe and clone picture multi threaded drawing. 333bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 334bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comstruct ThreadData { 335b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com ThreadData(SkCanvas* target, int* tileCounter, SkTDArray<SkRect>* tileRects, 336b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com const SkString* path, bool* success) 337bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com : fCanvas(target) 338b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com , fPath(path) 339b8e404aebe0f0d6f2508899c3405876a85704aaescroggo@google.com , fSuccess(success) 340b8e404aebe0f0d6f2508899c3405876a85704aaescroggo@google.com , fTileCounter(tileCounter) 341b8e404aebe0f0d6f2508899c3405876a85704aaescroggo@google.com , fTileRects(tileRects) { 342bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(target != NULL && tileCounter != NULL && tileRects != NULL); 343b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com // Success must start off true, and it will be set to false upon failure. 344b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkASSERT(success != NULL && *success); 345bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 346bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 347b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com int32_t nextTile(SkRect* rect) { 348b4773b4802236fab24cfc63ed8b9ed7eb35f65ccscroggo@google.com int32_t i = sk_atomic_inc(fTileCounter); 349b4773b4802236fab24cfc63ed8b9ed7eb35f65ccscroggo@google.com if (i < fTileRects->count()) { 350b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkASSERT(rect != NULL); 351b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com *rect = fTileRects->operator[](i); 352b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com return i; 353bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 354b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com return -1; 355bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 356bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 357bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // All of these are pointers to objects owned elsewhere 358bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkCanvas* fCanvas; 359b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com const SkString* fPath; 360b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com bool* fSuccess; 361bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comprivate: 362bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Shared by all threads, this states which is the next tile to be drawn. 363bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com int32_t* fTileCounter; 364bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Points to the array of rectangles. The array is already created before any threads are 365bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // started and then it is unmodified, so there is no danger of race conditions. 366bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com const SkTDArray<SkRect>* fTileRects; 367bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com}; 368bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 369bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 37058b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com// Draw using Pipe 37158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 372bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comstruct TileData : public ThreadData { 373bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com TileData(ThreadSafePipeController* controller, SkCanvas* canvas, int* tileCounter, 374b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkTDArray<SkRect>* tileRects, const SkString* path, bool* success) 375b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com : INHERITED(canvas, tileCounter, tileRects, path, success) 376bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fController(controller) {} 377bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 3788e073ba2d63f4d2aab7532f1421df00bb1f88003scroggo@google.com ThreadSafePipeController* fController; 379bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 380bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com typedef ThreadData INHERITED; 38158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com}; 38258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 38358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.comstatic void DrawTile(void* data) { 38458b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); 38558b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com TileData* tileData = static_cast<TileData*>(data); 38658b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 387b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkRect tileRect; 388b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com int32_t i; 389b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com while ((i = tileData->nextTile(&tileRect)) != -1) { 390b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com DrawTileToCanvas(tileData->fCanvas, tileRect, tileData->fController); 391070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com if (NULL != tileData->fPath && 392070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com !writeAppendNumber(tileData->fCanvas, tileData->fPath, i)) { 393b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com *tileData->fSuccess = false; 394b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com break; 395b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com } 396bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 397bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE(tileData); 398bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com} 39958b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 40058b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 40158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com// Draw using Picture 40258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 403bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comstruct CloneData : public ThreadData { 404b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com CloneData(SkPicture* clone, SkCanvas* target, int* tileCounter, SkTDArray<SkRect>* tileRects, 405b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com const SkString* path, bool* success) 406b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com : INHERITED(target, tileCounter, tileRects, path, success) 407bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com , fClone(clone) {} 408bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 40958b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com SkPicture* fClone; 410bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 411bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com typedef ThreadData INHERITED; 41258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com}; 41358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 414bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comstatic void DrawClonedTiles(void* data) { 41558b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); 41658b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com CloneData* cloneData = static_cast<CloneData*>(data); 41758b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 418b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com SkRect tileRect; 419b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com int32_t i; 420b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com while ((i = cloneData->nextTile(&tileRect)) != -1) { 421b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com DrawTileToCanvas(cloneData->fCanvas, tileRect, cloneData->fClone); 422070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com if (NULL != cloneData->fPath && 423070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com !writeAppendNumber(cloneData->fCanvas, cloneData->fPath, i)) { 424b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com *cloneData->fSuccess = false; 425b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com break; 426b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com } 427bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 428bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE(cloneData); 429bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com} 43058b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 43158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 43258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 433bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comvoid TiledPictureRenderer::setup() { 434bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (this->multiThreaded()) { 435bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Reset to zero so we start with the first tile. 436bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fTileCounter = 0; 437bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (fUsePipe) { 438bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Record the picture into the pipe controller. It is done here because unlike 439bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // SkPicture, the pipe is modified (bitmaps can be removed) by drawing. 440bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // fPipeController is deleted here after each call to render() except the last one and 441bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // in end() for the last one. 442bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (fPipeController != NULL) { 443bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE(fPipeController); 444bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 445bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fPipeController = SkNEW_ARGS(ThreadSafePipeController, (fTileRects.count())); 446bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkGPipeWriter writer; 447bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkCanvas* pipeCanvas = writer.startRecording(fPipeController, 448bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkGPipeWriter::kSimultaneousReaders_Flag); 449bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(fPicture != NULL); 450bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fPicture->draw(pipeCanvas); 451bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com writer.endRecording(); 452bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 453bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 454bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com} 455bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 45681f9d2e05be4902993345dac93337158345c660bscroggo@google.combool TiledPictureRenderer::render(const SkString* path) { 457acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkASSERT(fPicture != NULL); 458acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com if (NULL == fPicture) { 45981f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 460acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com } 461acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 462bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (this->multiThreaded()) { 463bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(fCanvasPool.count() == fNumThreads); 464bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkTDArray<SkThread*> threads; 465bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkThread::entryPointProc proc = fUsePipe ? DrawTile : DrawClonedTiles; 466b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com bool success = true; 467bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com for (int i = 0; i < fNumThreads; ++i) { 468bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // data will be deleted by the entryPointProc. 469bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com ThreadData* data; 470bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (fUsePipe) { 471b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com data = SkNEW_ARGS(TileData, (fPipeController, fCanvasPool[i], &fTileCounter, 472b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com &fTileRects, path, &success)); 473bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } else { 474bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkPicture* pic = (0 == i) ? fPicture : &fPictureClones[i-1]; 475b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com data = SkNEW_ARGS(CloneData, (pic, fCanvasPool[i], &fTileCounter, &fTileRects, path, 476b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com &success)); 47758b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com } 478bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkThread* thread = SkNEW_ARGS(SkThread, (proc, data)); 479bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com if (!thread->start()) { 480bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDebugf("Could not start %s thread %i.\n", (fUsePipe ? "pipe" : "picture"), i); 48158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com } 482bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com *threads.append() = thread; 48358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com } 484bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(threads.count() == fNumThreads); 485bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com for (int i = 0; i < fNumThreads; ++i) { 486bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkThread* thread = threads[i]; 487bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com thread->join(); 488bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkDELETE(thread); 489bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 490bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com threads.reset(); 491b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com return success; 49258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com } else { 493bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // For single thread, we really only need one canvas total. 494acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkCanvas* canvas = this->setupCanvas(fTileWidth, fTileHeight); 495acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkAutoUnref aur(canvas); 496acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 497070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com bool success = true; 498acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com for (int i = 0; i < fTileRects.count(); ++i) { 499bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com DrawTileToCanvas(canvas, fTileRects[i], fPicture); 500070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com if (NULL != path) { 501070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com success &= writeAppendNumber(canvas, path, i); 502acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com } 50358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com } 504070d354d51dac52a70f07d4b102392b89f2da5d7borenet@google.com return success; 505163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org } 506163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org} 507163b56734fe01c088581895a8e0b65ddf1cb4fa5keyar@chromium.org 508bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.comSkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) { 509bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkCanvas* canvas = this->INHERITED::setupCanvas(width, height); 510bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkASSERT(fPicture != NULL); 511bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // Clip the tile to an area that is completely in what the SkPicture says is the 512bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // drawn-to area. This is mostly important for tiles on the right and bottom edges 513bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // as they may go over this area and the picture may have some commands that 514bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com // draw outside of this area and so should not actually be written. 515bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkRect clip = SkRect::MakeWH(SkIntToScalar(fPicture->width()), 516bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com SkIntToScalar(fPicture->height())); 517bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->clipRect(clip); 518bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com return canvas; 519bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com} 520bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 521acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 5229a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com 5239a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.comvoid PlaybackCreationRenderer::setup() { 5249a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com SkCanvas* recorder = fReplayer.beginRecording(fPicture->width(), fPicture->height()); 5259a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fPicture->draw(recorder); 5269a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com} 5279a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com 52881f9d2e05be4902993345dac93337158345c660bscroggo@google.combool PlaybackCreationRenderer::render(const SkString*) { 5299a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fReplayer.endRecording(); 53081f9d2e05be4902993345dac93337158345c660bscroggo@google.com // Since this class does not actually render, return false. 53181f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 532451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 533451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 534451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 535