| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2012 Google Inc. | 
 | 3 |  * | 
 | 4 |  * Use of this source code is governed by a BSD-style license that can be | 
 | 5 |  * found in the LICENSE file. | 
 | 6 |  */ | 
 | 7 |  | 
 | 8 | #include "picture_utils.h" | 
 | 9 | #include "CopyTilesRenderer.h" | 
 | 10 | #include "SkCanvas.h" | 
 | 11 | #include "SkDevice.h" | 
 | 12 | #include "SkImageEncoder.h" | 
| robertphillips | 78c7127 | 2014-10-09 04:59:19 -0700 | [diff] [blame] | 13 | #include "SkMultiPictureDraw.h" | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 14 | #include "SkPicture.h" | 
 | 15 | #include "SkPixelRef.h" | 
 | 16 | #include "SkRect.h" | 
 | 17 | #include "SkString.h" | 
 | 18 |  | 
 | 19 | namespace sk_tools { | 
| krajcevski | b1aded8 | 2014-08-18 07:52:17 -0700 | [diff] [blame] | 20 | #if SK_SUPPORT_GPU | 
 | 21 |     CopyTilesRenderer::CopyTilesRenderer(const GrContext::Options& opts, int x, int y) | 
 | 22 |     : INHERITED(opts) | 
 | 23 |     , fXTilesPerLargeTile(x) | 
 | 24 |     , fYTilesPerLargeTile(y) { } | 
 | 25 | #else | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 26 |     CopyTilesRenderer::CopyTilesRenderer(int x, int y) | 
 | 27 |     : fXTilesPerLargeTile(x) | 
| krajcevski | b1aded8 | 2014-08-18 07:52:17 -0700 | [diff] [blame] | 28 |     , fYTilesPerLargeTile(y) { } | 
 | 29 | #endif | 
| robertphillips | ce4dd3d | 2014-07-07 13:46:35 -0700 | [diff] [blame] | 30 |     void CopyTilesRenderer::init(const SkPicture* pict, const SkString* writePath, | 
| commit-bot@chromium.org | 3f04517 | 2014-05-15 15:10:48 +0000 | [diff] [blame] | 31 |                                  const SkString* mismatchPath, const SkString* inputFilename, | 
| robertphillips | 78c7127 | 2014-10-09 04:59:19 -0700 | [diff] [blame] | 32 |                                  bool useChecksumBasedFilenames, bool useMultiPictureDraw) { | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 33 |         // Do not call INHERITED::init(), which would create a (potentially large) canvas which is | 
 | 34 |         // not used by bench_pictures. | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 35 |         SkASSERT(pict != NULL); | 
 | 36 |         // Only work with absolute widths (as opposed to percentages). | 
 | 37 |         SkASSERT(this->getTileWidth() != 0 && this->getTileHeight() != 0); | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 38 |         fPicture.reset(pict)->ref(); | 
| commit-bot@chromium.org | 3f04517 | 2014-05-15 15:10:48 +0000 | [diff] [blame] | 39 |         this->CopyString(&fWritePath, writePath); | 
 | 40 |         this->CopyString(&fMismatchPath, mismatchPath); | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 41 |         this->CopyString(&fInputFilename, inputFilename); | 
 | 42 |         fUseChecksumBasedFilenames = useChecksumBasedFilenames; | 
| robertphillips | 78c7127 | 2014-10-09 04:59:19 -0700 | [diff] [blame] | 43 |         fUseMultiPictureDraw = useMultiPictureDraw; | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 44 |         this->buildBBoxHierarchy(); | 
 | 45 |         // In order to avoid allocating a large canvas (particularly important for GPU), create one | 
 | 46 |         // canvas that is a multiple of the tile size, and draw portions of the picture. | 
 | 47 |         fLargeTileWidth = fXTilesPerLargeTile * this->getTileWidth(); | 
 | 48 |         fLargeTileHeight = fYTilesPerLargeTile * this->getTileHeight(); | 
 | 49 |         fCanvas.reset(this->INHERITED::setupCanvas(fLargeTileWidth, fLargeTileHeight)); | 
 | 50 |     } | 
 | 51 |  | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 52 |     bool CopyTilesRenderer::render(SkBitmap** out) { | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 53 |         int i = 0; | 
 | 54 |         bool success = true; | 
 | 55 |         SkBitmap dst; | 
| scroggo@google.com | c0d5e54 | 2012-12-13 21:40:48 +0000 | [diff] [blame] | 56 |         for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) { | 
 | 57 |             for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) { | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 58 |                 SkAutoCanvasRestore autoRestore(fCanvas, true); | 
| scroggo@google.com | 82ec0b0 | 2012-12-17 19:25:54 +0000 | [diff] [blame] | 59 |                 // Translate so that we draw the correct portion of the picture. | 
 | 60 |                 // Perform a postTranslate so that the scaleFactor does not interfere with the | 
 | 61 |                 // positioning. | 
 | 62 |                 SkMatrix mat(fCanvas->getTotalMatrix()); | 
 | 63 |                 mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); | 
 | 64 |                 fCanvas->setMatrix(mat); | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 65 |                 // Draw the picture | 
| robertphillips | 78c7127 | 2014-10-09 04:59:19 -0700 | [diff] [blame] | 66 |                 if (fUseMultiPictureDraw) { | 
 | 67 |                     SkMultiPictureDraw mpd; | 
 | 68 |  | 
 | 69 |                     mpd.add(fCanvas, fPicture); | 
 | 70 |  | 
 | 71 |                     mpd.draw(); | 
 | 72 |                 } else { | 
 | 73 |                     fCanvas->drawPicture(fPicture); | 
 | 74 |                 } | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 75 |                 // Now extract the picture into tiles | 
| reed | 52d9ac6 | 2014-06-30 09:05:34 -0700 | [diff] [blame] | 76 |                 SkBitmap baseBitmap; | 
 | 77 |                 fCanvas->readPixels(SkIRect::MakeSize(fCanvas->getBaseLayerSize()), &baseBitmap); | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 78 |                 SkIRect subset; | 
 | 79 |                 for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) { | 
 | 80 |                     for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) { | 
 | 81 |                         subset.set(tileX, tileY, tileX + this->getTileWidth(), | 
 | 82 |                                    tileY + this->getTileHeight()); | 
 | 83 |                         SkDEBUGCODE(bool extracted =) | 
 | 84 |                         baseBitmap.extractSubset(&dst, subset); | 
 | 85 |                         SkASSERT(extracted); | 
| commit-bot@chromium.org | 3f04517 | 2014-05-15 15:10:48 +0000 | [diff] [blame] | 86 |                         if (!fWritePath.isEmpty()) { | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 87 |                             // Similar to write() in PictureRenderer.cpp, but just encodes | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 88 |                             // a bitmap directly. | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 89 |                             // TODO: Share more common code with write() to do this, to properly | 
 | 90 |                             // write out the JSON summary, etc. | 
| tfarina | a8e2e15 | 2014-07-28 19:26:58 -0700 | [diff] [blame] | 91 |                             SkString pathWithNumber = SkOSPath::Join(fWritePath.c_str(), | 
 | 92 |                                                                      fInputFilename.c_str()); | 
| commit-bot@chromium.org | f5e315c | 2014-03-19 17:26:07 +0000 | [diff] [blame] | 93 |                             pathWithNumber.remove(pathWithNumber.size() - 4, 4); | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 94 |                             pathWithNumber.appendf("%i.png", i++); | 
 | 95 |                             SkBitmap copy; | 
 | 96 | #if SK_SUPPORT_GPU | 
 | 97 |                             if (isUsingGpuDevice()) { | 
 | 98 |                                 dst.pixelRef()->readPixels(©, &subset); | 
 | 99 |                             } else { | 
 | 100 | #endif | 
| commit-bot@chromium.org | 8a2ad3c | 2014-02-23 03:59:35 +0000 | [diff] [blame] | 101 |                                 dst.copyTo(©); | 
| scroggo@google.com | 4a26d9d | 2012-11-07 18:01:46 +0000 | [diff] [blame] | 102 | #if SK_SUPPORT_GPU | 
 | 103 |                             } | 
 | 104 | #endif | 
 | 105 |                             success &= SkImageEncoder::EncodeFile(pathWithNumber.c_str(), copy, | 
 | 106 |                                                                   SkImageEncoder::kPNG_Type, 100); | 
 | 107 |                         } | 
 | 108 |                     } | 
 | 109 |                 } | 
 | 110 |             } | 
 | 111 |         } | 
 | 112 |         return success; | 
 | 113 |     } | 
 | 114 |  | 
 | 115 |     SkString CopyTilesRenderer::getConfigNameInternal() { | 
 | 116 |         return SkString("copy_tiles"); | 
 | 117 |     } | 
 | 118 | } |