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" 11a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org#include "SkBitmapHasher.h" 12451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkCanvas.h" 131b1bcc3ceac9b4adbb4de68429903a5f721ffe62scroggo@google.com#include "SkData.h" 14451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkDevice.h" 1594d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com#include "SkDiscardableMemoryPool.h" 16451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkGPipe.h" 1758b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#if SK_SUPPORT_GPU 18fe1b536bb7af523995549b64ad19de6685e11411robertphillips@google.com#include "gl/GrGLDefines.h" 1958b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkGpuDevice.h" 2058b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#endif 2158b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkGraphics.h" 2258b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkImageEncoder.h" 23a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com#include "SkMaskFilter.h" 24ea82695325e2afc68f646fcc23fcae8b1bff6dc1keyar@chromium.org#include "SkMatrix.h" 2524c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org#include "SkOSFile.h" 26451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkPicture.h" 27770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h" 281b1bcc3ceac9b4adbb4de68429903a5f721ffe62scroggo@google.com#include "SkPictureUtils.h" 291b1bcc3ceac9b4adbb4de68429903a5f721ffe62scroggo@google.com#include "SkPixelRef.h" 30ea82695325e2afc68f646fcc23fcae8b1bff6dc1keyar@chromium.org#include "SkScalar.h" 31a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com#include "SkStream.h" 329299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org#include "SkString.h" 3358b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkTemplates.h" 34451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTDArray.h" 3558b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com#include "SkThreadUtils.h" 36451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org#include "SkTypes.h" 374ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org 38e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.comstatic inline SkScalar scalar_log2(SkScalar x) { 39e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.com static const SkScalar log2_conversion_factor = SkScalarDiv(1, SkScalarLog(2)); 403b85deb9c3c0889152ccbff02cf4417df161fe33skia.committer@gmail.com 41e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.com return SkScalarLog(x) * log2_conversion_factor; 42e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.com} 43e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.com 44451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgnamespace sk_tools { 45451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 46451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgenum { 47451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org kDefaultTileWidth = 256, 48451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org kDefaultTileHeight = 256 49451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org}; 50451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 512a65a238b0e688356aee09d08f3f8a317359b4d2mtkleinvoid PictureRenderer::init(const SkPicture* pict, 522a65a238b0e688356aee09d08f3f8a317359b4d2mtklein const SkString* writePath, 53ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkString* mismatchPath, 542a65a238b0e688356aee09d08f3f8a317359b4d2mtklein const SkString* inputFilename, 55ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool useChecksumBasedFilenames) { 563f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org this->CopyString(&fWritePath, writePath); 573f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org this->CopyString(&fMismatchPath, mismatchPath); 58f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org this->CopyString(&fInputFilename, inputFilename); 59f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org fUseChecksumBasedFilenames = useChecksumBasedFilenames; 60f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org 6178a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org SkASSERT(NULL == fPicture); 6278a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org SkASSERT(NULL == fCanvas.get()); 6349f085dddff10473b6ebf832a974288300224e60bsalomon if (fPicture || fCanvas.get()) { 649d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 659d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 669d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 679d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(pict != NULL); 6878a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == pict) { 699d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 709d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 719d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 7284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com fPicture.reset(pict)->ref(); 73a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org fCanvas.reset(this->setupCanvas()); 74a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org} 75a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 76f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgvoid PictureRenderer::CopyString(SkString* dest, const SkString* src) { 7749f085dddff10473b6ebf832a974288300224e60bsalomon if (src) { 78f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org dest->set(*src); 79f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org } else { 80f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org dest->reset(); 81f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org } 82f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org} 83f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org 84a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.comclass FlagsDrawFilter : public SkDrawFilter { 85a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.compublic: 86a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com FlagsDrawFilter(PictureRenderer::DrawFilterFlags* flags) : 87a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com fFlags(flags) {} 88a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com 89971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com virtual bool filter(SkPaint* paint, Type t) { 90a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com paint->setFlags(paint->getFlags() & ~fFlags[t] & SkPaint::kAllFlags); 91491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com if (PictureRenderer::kMaskFilter_DrawFilterFlag & fFlags[t]) { 92a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com SkMaskFilter* maskFilter = paint->getMaskFilter(); 9349f085dddff10473b6ebf832a974288300224e60bsalomon if (maskFilter) { 94457d8a77bed0160519fc5dfb67d0e02f9c3950a2reed@google.com paint->setMaskFilter(NULL); 95a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } 96a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } 97a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com if (PictureRenderer::kHinting_DrawFilterFlag & fFlags[t]) { 98a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com paint->setHinting(SkPaint::kNo_Hinting); 99a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } else if (PictureRenderer::kSlightHinting_DrawFilterFlag & fFlags[t]) { 100a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com paint->setHinting(SkPaint::kSlight_Hinting); 101a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } 102971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return true; 103a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } 104a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com 105a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.comprivate: 106a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com PictureRenderer::DrawFilterFlags* fFlags; 107a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com}; 108a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com 10982ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.comstatic void setUpFilter(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* drawFilters) { 110a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com if (drawFilters && !canvas->getDrawFilter()) { 111a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com canvas->setDrawFilter(SkNEW_ARGS(FlagsDrawFilter, (drawFilters)))->unref(); 112e3e940cf81dc46d872002ded98c1bd39c2daf1b0caryclark@google.com if (drawFilters[0] & PictureRenderer::kAAClip_DrawFilterFlag) { 113e3e940cf81dc46d872002ded98c1bd39c2daf1b0caryclark@google.com canvas->setAllowSoftClip(false); 114e3e940cf81dc46d872002ded98c1bd39c2daf1b0caryclark@google.com } 115a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com } 116a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com} 117a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com 118a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.orgSkCanvas* PictureRenderer::setupCanvas() { 119c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int width = this->getViewWidth(); 120c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int height = this->getViewHeight(); 121c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com return this->setupCanvas(width, height); 122a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org} 123a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 124a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.orgSkCanvas* PictureRenderer::setupCanvas(int width, int height) { 125a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com SkCanvas* canvas; 1264ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org switch(fDeviceType) { 1274ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org case kBitmap_DeviceType: { 1284ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org SkBitmap bitmap; 129a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org sk_tools::setup_bitmap(&bitmap, width, height); 130a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com canvas = SkNEW_ARGS(SkCanvas, (bitmap)); 1314ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 13282ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com break; 1334ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org#if SK_SUPPORT_GPU 1340556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com#if SK_ANGLE 1350556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com case kAngle_DeviceType: 1360556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com // fall through 1370556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com#endif 1386ab96733b85cebac99b378f998cd7dc10b286395rmistry@google.com#if SK_MESA 1396ab96733b85cebac99b378f998cd7dc10b286395rmistry@google.com case kMesa_DeviceType: 1406ab96733b85cebac99b378f998cd7dc10b286395rmistry@google.com // fall through 1416ab96733b85cebac99b378f998cd7dc10b286395rmistry@google.com#endif 1420fd5270ad69f5b99852d544158c989d2deda2c11commit-bot@chromium.org case kGPU_DeviceType: 1430fd5270ad69f5b99852d544158c989d2deda2c11commit-bot@chromium.org case kNVPR_DeviceType: { 144ae403b94967aa73fe0fd9f0afb612d5773aeafbfcommit-bot@chromium.org SkAutoTUnref<GrSurface> target; 1450556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com if (fGrContext) { 1460556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com // create a render target to back the device 1470556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com GrTextureDesc desc; 1480556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com desc.fConfig = kSkia8888_GrPixelConfig; 1490556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 1500556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com desc.fWidth = width; 1510556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com desc.fHeight = height; 152f6a90332ae21414cf19630764d4371ffd24ac0ccjvanverth@google.com desc.fSampleCnt = fSampleCount; 153ae403b94967aa73fe0fd9f0afb612d5773aeafbfcommit-bot@chromium.org target.reset(fGrContext->createUncachedTexture(desc, NULL, 0)); 1540556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com } 155ae403b94967aa73fe0fd9f0afb612d5773aeafbfcommit-bot@chromium.org if (NULL == target.get()) { 1560556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com SkASSERT(0); 1570556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com return NULL; 1580556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com } 1590556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com 1604a8126e7f81384526629b1e21bf89b632ea13cd9reed SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, 1614a8126e7f81384526629b1e21bf89b632ea13cd9reed SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType))); 162a36223764466c964ed1035bf6f152ba55168f61ecaryclark@google.com canvas = SkNEW_ARGS(SkCanvas, (device.get())); 1630556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com break; 1644ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 1654ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org#endif 1664ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org default: 1674ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org SkASSERT(0); 16882ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com return NULL; 1694ea96c5e5449248780acfeb3cef4ec812f955d74keyar@chromium.org } 17082ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com setUpFilter(canvas, fDrawFilters); 17182ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com this->scaleToScaleFactor(canvas); 17217cc3eaeafd507a78b7f713f8981a6ed67569964commit-bot@chromium.org 17317cc3eaeafd507a78b7f713f8981a6ed67569964commit-bot@chromium.org // Pictures often lie about their extent (i.e., claim to be 100x100 but 17417cc3eaeafd507a78b7f713f8981a6ed67569964commit-bot@chromium.org // only ever draw to 90x100). Clear here so the undrawn portion will have 17517cc3eaeafd507a78b7f713f8981a6ed67569964commit-bot@chromium.org // a consistent color 17617cc3eaeafd507a78b7f713f8981a6ed67569964commit-bot@chromium.org canvas->clear(SK_ColorTRANSPARENT); 17782ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com return canvas; 17882ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com} 179a474ce3c0b7f72539e20a57b583b99046dfb7706keyar@chromium.org 18082ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.comvoid PictureRenderer::scaleToScaleFactor(SkCanvas* canvas) { 18182ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com SkASSERT(canvas != NULL); 18282ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com if (fScaleFactor != SK_Scalar1) { 18382ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com canvas->scale(fScaleFactor, fScaleFactor); 18482ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com } 1859d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org} 1869d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 1879d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid PictureRenderer::end() { 18808085f808b808bfb14fcb247bb8cb1a5e8d43dccscroggo@google.com this->resetState(true); 18984b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com fPicture.reset(NULL); 1909d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org fCanvas.reset(NULL); 1919d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org} 1929d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 193c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.comint PictureRenderer::getViewWidth() { 194c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com SkASSERT(fPicture != NULL); 195a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips int width = SkScalarCeilToInt(fPicture->cullRect().width() * fScaleFactor); 196c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com if (fViewport.width() > 0) { 197c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com width = SkMin32(width, fViewport.width()); 198c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com } 199c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com return width; 200c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com} 201c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com 202c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.comint PictureRenderer::getViewHeight() { 203c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com SkASSERT(fPicture != NULL); 204a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips int height = SkScalarCeilToInt(fPicture->cullRect().height() * fScaleFactor); 205c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com if (fViewport.height() > 0) { 206c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com height = SkMin32(height, fViewport.height()); 207c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com } 208c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com return height; 209c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com} 210c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com 2119313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org/** Converts fPicture to a picture that uses a BBoxHierarchy. 2129313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org * PictureRenderer subclasses that are used to test picture playback 2139313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org * should call this method during init. 2149313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org */ 2159313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.orgvoid PictureRenderer::buildBBoxHierarchy() { 21649f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fPicture); 21749f085dddff10473b6ebf832a974288300224e60bsalomon if (kNone_BBoxHierarchyType != fBBoxHierarchyType && fPicture) { 2185fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); 2195fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkPictureRecorder recorder; 220a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* canvas = recorder.beginRecording(fPicture->cullRect().width(), 221a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips fPicture->cullRect().height(), 2225fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org factory.get(), 22384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->recordFlags()); 224c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips fPicture->playback(canvas); 22584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com fPicture.reset(recorder.endRecording()); 2269313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org } 2279313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org} 2289313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org 22908085f808b808bfb14fcb247bb8cb1a5e8d43dccscroggo@google.comvoid PictureRenderer::resetState(bool callFinish) { 23028136b308fe467da113983cfee332faea133cd8akeyar@chromium.org#if SK_SUPPORT_GPU 2316177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com SkGLContextHelper* glContext = this->getGLContext(); 2320556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com if (NULL == glContext) { 2330556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com SkASSERT(kBitmap_DeviceType == fDeviceType); 2340556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com return; 2350556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com } 23628136b308fe467da113983cfee332faea133cd8akeyar@chromium.org 2370556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com fGrContext->flush(); 23851c040ed1e8c50bec4297bbe25242f644b40b0b7commit-bot@chromium.org glContext->swapBuffers(); 2390556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com if (callFinish) { 2400556ea0ede7066b9b3ed9f03f5a6eb72cd718897scroggo@google.com SK_GL(*glContext, Finish()); 24177a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org } 242a40c20df0e4c5d04acb0841d70127778c0a779eckeyar@chromium.org#endif 24377a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org} 24477a5522d0e4437ef2b856acd7b135b6afda64ceekeyar@chromium.org 24594d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.comvoid PictureRenderer::purgeTextures() { 24694d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool(); 24794d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com 24894d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com pool->dumpPool(); 24994d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com 25094d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com#if SK_SUPPORT_GPU 25194d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com SkGLContextHelper* glContext = this->getGLContext(); 25294d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com if (NULL == glContext) { 25394d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com SkASSERT(kBitmap_DeviceType == fDeviceType); 25494d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com return; 25594d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com } 25694d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com 25794d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com // resetState should've already done this 25894d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com fGrContext->flush(); 25994d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com 26094d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com fGrContext->purgeAllUnlockedResources(); 26194d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com#endif 26294d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com} 26394d8f1ed6116780346ffa39ed683f1977786434arobertphillips@google.com 264b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com/** 2654610a465b61f27ea5de2254a0e0b79ea2f327617commit-bot@chromium.org * Write the canvas to an image file and/or JSON summary. 266f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org * 267b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com * @param canvas Must be non-null. Canvas to be written to a file. 2683f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org * @param writePath If nonempty, write the binary image to a file within this directory. 2693f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org * @param mismatchPath If nonempty, write the binary image to a file within this directory, 2703f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org * but only if the image does not match expectations. 271f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org * @param inputFilename If we are writing out a binary image, use this to build its filename. 2724610a465b61f27ea5de2254a0e0b79ea2f327617commit-bot@chromium.org * @param jsonSummaryPtr If not null, add image results (checksum) to this summary. 273f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org * @param useChecksumBasedFilenames If true, use checksum-based filenames when writing to disk. 27424c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org * @param tileNumberPtr If not null, which tile number this image contains. 275a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * 2764610a465b61f27ea5de2254a0e0b79ea2f327617commit-bot@chromium.org * @return bool True if the operation completed successfully. 277b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com */ 2783f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.orgstatic bool write(SkCanvas* canvas, const SkString& writePath, const SkString& mismatchPath, 2793f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org const SkString& inputFilename, ImageResultsAndExpectations *jsonSummaryPtr, 2803f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org bool useChecksumBasedFilenames, const int* tileNumberPtr=NULL) { 28181f9d2e05be4902993345dac93337158345c660bscroggo@google.com SkASSERT(canvas != NULL); 282b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com if (NULL == canvas) { 2839299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org return false; 2849299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org } 2859299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 2869299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org SkBitmap bitmap; 28781f9d2e05be4902993345dac93337158345c660bscroggo@google.com SkISize size = canvas->getDeviceSize(); 288205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org setup_bitmap(&bitmap, size.width(), size.height()); 289f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org 29081f9d2e05be4902993345dac93337158345c660bscroggo@google.com canvas->readPixels(&bitmap, 0, 0); 291205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org force_all_opaque(bitmap); 292205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org BitmapAndDigest bitmapAndDigest(bitmap); 2939299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 29424c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org SkString escapedInputFilename(inputFilename); 29524c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org replace_char(&escapedInputFilename, '.', '_'); 29624c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org 297f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org // TODO(epoger): what about including the config type within outputFilename? That way, 298f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org // we could combine results of different config types without conflicting filenames. 29924c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org SkString outputFilename; 30024c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org const char *outputSubdirPtr = NULL; 30124c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org if (useChecksumBasedFilenames) { 30285b438dfab7f6ec1fd46dbc19215ccf2171ad6aeepoger ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr(); 30324c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputSubdirPtr = escapedInputFilename.c_str(); 304205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org outputFilename.set(imageDigestPtr->getHashType()); 305205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org outputFilename.append("_"); 306205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org outputFilename.appendU64(imageDigestPtr->getHashValue()); 30724c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } else { 30824c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputFilename.set(escapedInputFilename); 30949f085dddff10473b6ebf832a974288300224e60bsalomon if (tileNumberPtr) { 31024c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputFilename.append("-tile"); 31124c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputFilename.appendS32(*tileNumberPtr); 31224c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } 313f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org } 31424c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputFilename.append(".png"); 3159299eded3838a7997235ff033aa3b9a8d4c6d4d4keyar@chromium.org 31649f085dddff10473b6ebf832a974288300224e60bsalomon if (jsonSummaryPtr) { 31785b438dfab7f6ec1fd46dbc19215ccf2171ad6aeepoger ImageDigest *imageDigestPtr = bitmapAndDigest.getImageDigestPtr(); 31824c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org SkString outputRelativePath; 31924c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org if (outputSubdirPtr) { 32024c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputRelativePath.set(outputSubdirPtr); 32124c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputRelativePath.append("/"); // always use "/", even on Windows 32224c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputRelativePath.append(outputFilename); 32324c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } else { 32424c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org outputRelativePath.set(outputFilename); 32524c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } 32624c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org 32724c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org jsonSummaryPtr->add(inputFilename.c_str(), outputRelativePath.c_str(), 328205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org *imageDigestPtr, tileNumberPtr); 3293f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org if (!mismatchPath.isEmpty() && 33085b438dfab7f6ec1fd46dbc19215ccf2171ad6aeepoger !jsonSummaryPtr->getExpectation(inputFilename.c_str(), 33185b438dfab7f6ec1fd46dbc19215ccf2171ad6aeepoger tileNumberPtr).matches(*imageDigestPtr)) { 3323f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org if (!write_bitmap_to_disk(bitmap, mismatchPath, outputSubdirPtr, outputFilename)) { 3333f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org return false; 3343f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org } 3353f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org } 336b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com } 337f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org 3383f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org if (writePath.isEmpty()) { 3394610a465b61f27ea5de2254a0e0b79ea2f327617commit-bot@chromium.org return true; 34024c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } else { 3413f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org return write_bitmap_to_disk(bitmap, writePath, outputSubdirPtr, outputFilename); 34224c568c1597de9f54df8cea3b46f2e93028a5aeccommit-bot@chromium.org } 343b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com} 344b6e806bf17ffcca0c147a7dab4fba104fe928a58scroggo@google.com 345acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 346acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 347fd9720cfec6bc50fa77d40ffdf2f6cb4b5150d4edjsollen@google.comSkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) { 348fd9720cfec6bc50fa77d40ffdf2f6cb4b5150d4edjsollen@google.com // defer the canvas setup until the render step 349fd9720cfec6bc50fa77d40ffdf2f6cb4b5150d4edjsollen@google.com return NULL; 350fd9720cfec6bc50fa77d40ffdf2f6cb4b5150d4edjsollen@google.com} 351fd9720cfec6bc50fa77d40ffdf2f6cb4b5150d4edjsollen@google.com 352672588b684d484dce6ae251e9e163e4a46924322reed@google.com// the size_t* parameter is deprecated, so we ignore it 353672588b684d484dce6ae251e9e163e4a46924322reed@google.comstatic SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) { 3541b1bcc3ceac9b4adbb4de68429903a5f721ffe62scroggo@google.com return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100); 355a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com} 356a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com 357f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgbool RecordPictureRenderer::render(SkBitmap** out) { 3585fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); 3595fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkPictureRecorder recorder; 360a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(this->getViewWidth()), 361a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(this->getViewHeight()), 3625fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org factory.get(), 36384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->recordFlags()); 36484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->scaleToScaleFactor(canvas); 365c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips fPicture->playback(canvas); 36684b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 3673f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org if (!fWritePath.isEmpty()) { 368a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com // Record the new picture as a new SKP with PNG encoded bitmaps. 369a8e2e1504b9af6ba791637f228debaa23953064atfarina SkString skpPath = SkOSPath::Join(fWritePath.c_str(), fInputFilename.c_str()); 370a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com SkFILEWStream stream(skpPath.c_str()); 37184b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com picture->serialize(&stream, &encode_bitmap_to_data); 372a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com return true; 373a9e3a369c18c6d5f41724e837e3ba0fa87d8c559scroggo@google.com } 37481f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 3759a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com} 3769a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com 3770a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.comSkString RecordPictureRenderer::getConfigNameInternal() { 3780a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com return SkString("record"); 3790a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com} 3800a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 381acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 382acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 383f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgbool PipePictureRenderer::render(SkBitmap** out) { 3849d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fCanvas.get() != NULL); 3859d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fPicture != NULL); 38678a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == fCanvas.get() || NULL == fPicture) { 38781f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 3889d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 3899d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 3909d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org PipeController pipeController(fCanvas.get()); 391451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org SkGPipeWriter writer; 392451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 3939b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips pipeCanvas->drawPicture(fPicture); 394451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org writer.endRecording(); 3959a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fCanvas->flush(); 39649f085dddff10473b6ebf832a974288300224e60bsalomon if (out) { 39784f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com *out = SkNEW(SkBitmap); 398a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 399a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkScalarCeilToInt(fPicture->cullRect().height())); 40084f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com fCanvas->readPixels(*out, 0, 0); 401a7d8e3e990c43aedda6a66aa211f175213ac54c0skia.committer@gmail.com } 4028991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org if (fEnableWrites) { 4038991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr, 4048991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org fUseChecksumBasedFilenames); 4058991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org } else { 4068991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org return true; 4078991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org } 408451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 409451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 4100a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.comSkString PipePictureRenderer::getConfigNameInternal() { 4110a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com return SkString("pipe"); 4120a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com} 4130a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 414acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 415acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 416ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsvoid SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath, 4173f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org const SkString* mismatchPath, const SkString* inputFilename, 4183f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org bool useChecksumBasedFilenames) { 4193f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames); 4209313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org this->buildBBoxHierarchy(); 4219313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org} 4229313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org 423f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgbool SimplePictureRenderer::render(SkBitmap** out) { 4249d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org SkASSERT(fCanvas.get() != NULL); 42549f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fPicture); 42678a35c5f1dcc00b2b442069a94f9e7c996f8d7f9keyar@chromium.org if (NULL == fCanvas.get() || NULL == fPicture) { 42781f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 4289d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 4299d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 4309b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips fCanvas->drawPicture(fPicture); 4319a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com fCanvas->flush(); 43249f085dddff10473b6ebf832a974288300224e60bsalomon if (out) { 43384f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com *out = SkNEW(SkBitmap); 434a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 435a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkScalarCeilToInt(fPicture->cullRect().height())); 43684f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com fCanvas->readPixels(*out, 0, 0); 43784f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 4388991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org if (fEnableWrites) { 4398991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr, 4408991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org fUseChecksumBasedFilenames); 4418991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org } else { 4428991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org return true; 4438991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org } 444451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 445451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 4460a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.comSkString SimplePictureRenderer::getConfigNameInternal() { 4470a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com return SkString("simple"); 4480a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com} 4490a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 450acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 451acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com 452b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#if SK_SUPPORT_GPU 453b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevskiTiledPictureRenderer::TiledPictureRenderer(const GrContext::Options& opts) 4542a65a238b0e688356aee09d08f3f8a317359b4d2mtklein : INHERITED(opts) 455b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski , fTileWidth(kDefaultTileWidth) 456b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#else 457451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.orgTiledPictureRenderer::TiledPictureRenderer() 458a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com : fTileWidth(kDefaultTileWidth) 459b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#endif 460b947b91794f47cc92b17c83e570536f5e315a118rileya@google.com , fTileHeight(kDefaultTileHeight) 461a04dc02b118363fedf3a7b11cfcdab886d368f8arileya@google.com , fTileWidthPercentage(0.0) 462b947b91794f47cc92b17c83e570536f5e315a118rileya@google.com , fTileHeightPercentage(0.0) 463cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com , fTileMinPowerOf2Width(0) 464cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com , fCurrentTileOffset(-1) 465cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com , fTilesX(0) 466cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com , fTilesY(0) { } 467451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 468ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsvoid TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath, 4693f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org const SkString* mismatchPath, const SkString* inputFilename, 4703f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org bool useChecksumBasedFilenames) { 47149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(pict); 472acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkASSERT(0 == fTileRects.count()); 473acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com if (NULL == pict || fTileRects.count() != 0) { 4749d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org return; 4759d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org } 4769d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org 477acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // Do not call INHERITED::init(), which would create a (potentially large) canvas which is not 478acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // used by bench_pictures. 47984b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com fPicture.reset(pict)->ref(); 4803f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org this->CopyString(&fWritePath, writePath); 4813f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org this->CopyString(&fMismatchPath, mismatchPath); 482f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org this->CopyString(&fInputFilename, inputFilename); 483f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.org fUseChecksumBasedFilenames = useChecksumBasedFilenames; 484a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com this->buildBBoxHierarchy(); 485cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org 486cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org if (fTileWidthPercentage > 0) { 487a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips fTileWidth = SkScalarCeilToInt(float(fTileWidthPercentage * fPicture->cullRect().width() / 100)); 488cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org } 489cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org if (fTileHeightPercentage > 0) { 490a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips fTileHeight = SkScalarCeilToInt(float(fTileHeightPercentage * fPicture->cullRect().height() / 100)); 491cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org } 492cc6e5efe03bfeda903d67d2bacd9ed0be58572bakeyar@chromium.org 493f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org if (fTileMinPowerOf2Width > 0) { 494f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org this->setupPowerOf2Tiles(); 495f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } else { 496f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org this->setupTiles(); 497f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 498cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fCanvas.reset(this->setupCanvas(fTileWidth, fTileHeight)); 499cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com // Initialize to -1 so that the first call to nextTile will set this up to draw tile 0 on the 500cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com // first call to drawCurrentTile. 501cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fCurrentTileOffset = -1; 502451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 503451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 5049d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::end() { 505bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com fTileRects.reset(); 5069d696c0d04548520af08252e577d2ca88012a239keyar@chromium.org this->INHERITED::end(); 507451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 508451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 5099d696c0d04548520af08252e577d2ca88012a239keyar@chromium.orgvoid TiledPictureRenderer::setupTiles() { 510c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com // Only use enough tiles to cover the viewport 511c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int width = this->getViewWidth(); 512c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int height = this->getViewHeight(); 513c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com 514cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesX = fTilesY = 0; 515c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) { 516cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesY++; 517c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com for (int tile_x_start = 0; tile_x_start < width; tile_x_start += fTileWidth) { 518cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com if (0 == tile_y_start) { 519cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com // Only count tiles in the X direction on the first pass. 520cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesX++; 521cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com } 522acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), 523acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(tile_y_start), 524acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileWidth), 525acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileHeight)); 526f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 527f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 528f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org} 529f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 530cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.combool TiledPictureRenderer::tileDimensions(int &x, int &y) { 531cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com if (fTileRects.count() == 0 || NULL == fPicture) { 532cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com return false; 533cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com } 534cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com x = fTilesX; 535cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com y = fTilesY; 536cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com return true; 537cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com} 538cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com 539f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// The goal of the powers of two tiles is to minimize the amount of wasted tile 540f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// space in the width-wise direction and then minimize the number of tiles. The 541f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// constraints are that every tile must have a pixel width that is a power of 542f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// two and also be of some minimal width (that is also a power of two). 543f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// 54458b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com// This is solved by first taking our picture size and rounding it up to the 545f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// multiple of the minimal width. The binary representation of this rounded 546f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// value gives us the tiles we need: a bit of value one means we need a tile of 547f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org// that size. 548f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.orgvoid TiledPictureRenderer::setupPowerOf2Tiles() { 549c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com // Only use enough tiles to cover the viewport 550c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int width = this->getViewWidth(); 551c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com const int height = this->getViewHeight(); 552c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com 553c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com int rounded_value = width; 554c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com if (width % fTileMinPowerOf2Width != 0) { 555c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com rounded_value = width - (width % fTileMinPowerOf2Width) + fTileMinPowerOf2Width; 556f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 557f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 558e15b2f5296a65c92be477a71ddf9eae9d95eddcereed@google.com int num_bits = SkScalarCeilToInt(scalar_log2(SkIntToScalar(width))); 559f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int largest_possible_tile_size = 1 << num_bits; 560f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 561cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesX = fTilesY = 0; 562f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org // The tile height is constant for a particular picture. 563c0d5e549ab8d594a5da8db417db39622e9491fffscroggo@google.com for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) { 564cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesY++; 565f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int tile_x_start = 0; 566f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org int current_width = largest_possible_tile_size; 567acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough 568acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com // to draw each tile. 569acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com fTileWidth = current_width; 570f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 571f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org while (current_width >= fTileMinPowerOf2Width) { 572f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org // It is very important this is a bitwise AND. 573f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org if (current_width & rounded_value) { 574cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com if (0 == tile_y_start) { 575cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com // Only count tiles in the X direction on the first pass. 576cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com fTilesX++; 577cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com } 578acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), 579acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(tile_y_start), 580acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(current_width), 581acfb30e5bb797249f4ec41edda4c4d4b86e0e5d0scroggo@google.com SkIntToScalar(fTileHeight)); 582f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org tile_x_start += current_width; 583f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org } 584f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org 585f4959ab11827bef99e8985031feb457cae1f987akeyar@chromium.org current_width >>= 1; 586451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org } 587451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org } 588451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 589451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 590bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com/** 591145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org * Draw the specified picture to the canvas translated to rectangle provided, so that this mini 592bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * canvas represents the rectangle's portion of the overall picture. 593bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * Saves and restores so that the initial clip and matrix return to their state before this function 594bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com * is called. 595bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com */ 5962a65a238b0e688356aee09d08f3f8a317359b4d2mtkleinstatic void draw_tile_to_canvas(SkCanvas* canvas, 5972a65a238b0e688356aee09d08f3f8a317359b4d2mtklein const SkRect& tileRect, 598ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPicture* picture) { 599bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com int saveCount = canvas->save(); 60082ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // Translate so that we draw the correct portion of the picture. 60182ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // Perform a postTranslate so that the scaleFactor does not interfere with the positioning. 60282ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com SkMatrix mat(canvas->getTotalMatrix()); 60382ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com mat.postTranslate(-tileRect.fLeft, -tileRect.fTop); 60482ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com canvas->setMatrix(mat); 6059b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas->drawPicture(picture); 606bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->restoreToCount(saveCount); 607bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com canvas->flush(); 608451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 609451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 61058b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 611bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 612a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org/** 613a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * Copies the entirety of the src bitmap (typically a tile) into a portion of the dst bitmap. 614a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * If the src bitmap is too large to fit within the dst bitmap after the x and y 615a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * offsets have been applied, any excess will be ignored (so only the top-left portion of the 616a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * src bitmap will be copied). 617a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * 618a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * @param src source bitmap 619a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * @param dst destination bitmap 620a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * @param xOffset x-offset within destination bitmap 621a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org * @param yOffset y-offset within destination bitmap 622a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org */ 623a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.orgstatic void bitmapCopyAtOffset(const SkBitmap& src, SkBitmap* dst, 624a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org int xOffset, int yOffset) { 625a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org for (int y = 0; y <src.height() && y + yOffset < dst->height() ; y++) { 626a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org for (int x = 0; x < src.width() && x + xOffset < dst->width() ; x++) { 627a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org *dst->getAddr32(xOffset + x, yOffset + y) = *src.getAddr32(x, y); 62884f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 62984f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 63084f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com} 63184f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com 632cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.combool TiledPictureRenderer::nextTile(int &i, int &j) { 633cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com if (++fCurrentTileOffset < fTileRects.count()) { 634cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com i = fCurrentTileOffset % fTilesX; 635cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com j = fCurrentTileOffset / fTilesX; 636cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com return true; 637cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com } 638cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com return false; 639cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com} 640cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com 641cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.comvoid TiledPictureRenderer::drawCurrentTile() { 642cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com SkASSERT(fCurrentTileOffset >= 0 && fCurrentTileOffset < fTileRects.count()); 643145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture); 644cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com} 645cbcef708914f3b5e9bb63ad3d87261378026e29bscroggo@google.com 646f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgbool TiledPictureRenderer::render(SkBitmap** out) { 647a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com SkASSERT(fPicture != NULL); 648a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com if (NULL == fPicture) { 649a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com return false; 650bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 651bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com 65284f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com SkBitmap bitmap; 65384f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com if (out){ 65484f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com *out = SkNEW(SkBitmap); 655a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), 656a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkScalarCeilToInt(fPicture->cullRect().height())); 65784f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com setup_bitmap(&bitmap, fTileWidth, fTileHeight); 65884f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 659a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com bool success = true; 660a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com for (int i = 0; i < fTileRects.count(); ++i) { 661145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture); 6628991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org if (fEnableWrites) { 6638991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr, 6648991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org fUseChecksumBasedFilenames, &i); 6658991c67f0c1b9364bb12dfb0f32a53bd5a3357f3commit-bot@chromium.org } 66649f085dddff10473b6ebf832a974288300224e60bsalomon if (out) { 66784f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com if (fCanvas->readPixels(&bitmap, 0, 0)) { 668a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org // Add this tile to the entire bitmap. 669a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i].left()), 670a3f882c4756bd8b9b6449dcc60b6d884ee0cc8edcommit-bot@chromium.org SkScalarFloorToInt(fTileRects[i].top())); 67184f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } else { 67284f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com success = false; 67384f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 67484f548cc9daf77bb3ee7c59ad986eebe9ad1168eedisonn@google.com } 675bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com } 676a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com return success; 677bcdf2ec50dfd170959cc2db67c49f6dac084be03scroggo@google.com} 67858b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 679a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.comSkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) { 680a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com SkCanvas* canvas = this->INHERITED::setupCanvas(width, height); 68149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(fPicture); 68282ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This 68382ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // is mostly important for tiles on the right and bottom edges as they may go over this area and 68482ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // the picture may have some commands that draw outside of this area and so should not actually 68582ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // be written. 68682ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set 68782ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com // by INHERITED::setupCanvas. 68882ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com SkRegion clipRegion; 68982ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight()); 69082ec0b00f380906c1cdeb4b4cc4a355264ab3882scroggo@google.com canvas->clipRegion(clipRegion); 691a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com return canvas; 692a62da2fee72172a630c2d1dba0e529b357743662scroggo@google.com} 6930a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 6940a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.comSkString TiledPictureRenderer::getConfigNameInternal() { 6950a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com SkString name; 6960a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com if (fTileMinPowerOf2Width > 0) { 6970a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.append("pow2tile_"); 6980a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.appendf("%i", fTileMinPowerOf2Width); 6990a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } else { 7000a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.append("tile_"); 7010a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com if (fTileWidthPercentage > 0) { 7020a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.appendf("%.f%%", fTileWidthPercentage); 7030a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } else { 7040a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.appendf("%i", fTileWidth); 7050a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } 7060a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } 7070a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.append("x"); 7080a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com if (fTileHeightPercentage > 0) { 7090a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.appendf("%.f%%", fTileHeightPercentage); 7100a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } else { 7110a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com name.appendf("%i", fTileHeight); 7120a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com } 7130a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com return name; 7140a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com} 7150a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 71658b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com/////////////////////////////////////////////////////////////////////////////////////////////// 71758b4ead36c62d8c0256ee4da554f3df2744d904cscroggo@google.com 7189a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.comvoid PlaybackCreationRenderer::setup() { 7195fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); 7205fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org fRecorder.reset(SkNEW(SkPictureRecorder)); 721a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* canvas = fRecorder->beginRecording(SkIntToScalar(this->getViewWidth()), 722a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(this->getViewHeight()), 7235fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org factory.get(), 72484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->recordFlags()); 72584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com this->scaleToScaleFactor(canvas); 7269b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas->drawPicture(fPicture); 7279a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com} 7289a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com 729f5e315ccf1ae2941f7cf53fa53e5c8c4bb665fe1commit-bot@chromium.orgbool PlaybackCreationRenderer::render(SkBitmap** out) { 73084b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com fPicture.reset(fRecorder->endRecording()); 73181f9d2e05be4902993345dac93337158345c660bscroggo@google.com // Since this class does not actually render, return false. 73281f9d2e05be4902993345dac93337158345c660bscroggo@google.com return false; 733451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 734451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org 7350a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.comSkString PlaybackCreationRenderer::getConfigNameInternal() { 7360a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com return SkString("playback_creation"); 7370a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com} 7380a049b861e18c9c1ede865b8acbcbedc3dd10b43scroggo@google.com 7399313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org/////////////////////////////////////////////////////////////////////////////////////////////// 7409313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org// SkPicture variants for each BBoxHierarchy type 7419313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org 7425fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.orgSkBBHFactory* PictureRenderer::getFactory() { 7439313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org switch (fBBoxHierarchyType) { 7449313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org case kNone_BBoxHierarchyType: 74584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com return NULL; 7469313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org case kRTree_BBoxHierarchyType: 7475fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org return SkNEW(SkRTreeFactory); 7487b53706a7d596a2d8dce6cfe5b543264e5a37239junov@chromium.org case kTileGrid_BBoxHierarchyType: 7495fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org return SkNEW_ARGS(SkTileGridFactory, (fGridInfo)); 7509313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org } 7519313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org SkASSERT(0); // invalid bbhType 7529313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org return NULL; 753451bb9f801d668275394ca5bd57f238e13cf3d17keyar@chromium.org} 7549313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org 755fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com/////////////////////////////////////////////////////////////////////////////// 756fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com 757fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.comclass GatherRenderer : public PictureRenderer { 758fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.compublic: 759b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#if SK_SUPPORT_GPU 760b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski GatherRenderer(const GrContext::Options& opts) : INHERITED(opts) { } 761b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#endif 762b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski 7638ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE { 764a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->cullRect().width()), 765a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(fPicture->cullRect().height())); 766fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds); 767fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com SkSafeUnref(data); 768c7b4be7f110bc7b487c3c3f28d82877584e74c2fskia.committer@gmail.com 7693f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org return (fWritePath.isEmpty()); // we don't have anything to write 770fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com } 771c7b4be7f110bc7b487c3c3f28d82877584e74c2fskia.committer@gmail.com 772fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.comprivate: 773fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com virtual SkString getConfigNameInternal() SK_OVERRIDE { 774fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com return SkString("gather_pixelrefs"); 775fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com } 776b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski 777b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski typedef PictureRenderer INHERITED; 778fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com}; 779fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com 780b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#if SK_SUPPORT_GPU 781b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevskiPictureRenderer* CreateGatherPixelRefsRenderer(const GrContext::Options& opts) { 782b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski return SkNEW_ARGS(GatherRenderer, (opts)); 783b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski} 784b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#else 785fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.comPictureRenderer* CreateGatherPixelRefsRenderer() { 786fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com return SkNEW(GatherRenderer); 787fe7b1ed30a75cecfe80d1ba4d1f60295e99aeef0reed@google.com} 788b1aded8edd1d809cded20ff546c6e9218b43cda4krajcevski#endif 789c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com 7909313ca4bde606a18f29214eea8b8e47312b8fd9cjunov@chromium.org} // namespace sk_tools 791