Index: tools/PictureRenderer.cpp |
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp |
index 705849d01acd92348f60f506f554ccf24cf38435..89f2cda3dd99406ecd23214197cab673df80909d 100644 |
--- a/tools/PictureRenderer.cpp |
+++ b/tools/PictureRenderer.cpp |
@@ -22,6 +22,7 @@ |
#include "SkImageEncoder.h" |
#include "SkMaskFilter.h" |
#include "SkMatrix.h" |
+#include "SkMultiPictureDraw.h" |
#include "SkOSFile.h" |
#include "SkPicture.h" |
#include "SkPictureRecorder.h" |
@@ -30,6 +31,7 @@ |
#include "SkScalar.h" |
#include "SkStream.h" |
#include "SkString.h" |
+#include "SkSurface.h" |
#include "SkTemplates.h" |
#include "SkTDArray.h" |
#include "SkThreadUtils.h" |
@@ -52,11 +54,13 @@ void PictureRenderer::init(const SkPicture* pict, |
const SkString* writePath, |
const SkString* mismatchPath, |
const SkString* inputFilename, |
- bool useChecksumBasedFilenames) { |
+ bool useChecksumBasedFilenames, |
+ bool useMultiPictureDraw) { |
this->CopyString(&fWritePath, writePath); |
this->CopyString(&fMismatchPath, mismatchPath); |
this->CopyString(&fInputFilename, inputFilename); |
fUseChecksumBasedFilenames = useChecksumBasedFilenames; |
+ fUseMultiPictureDraw = useMultiPictureDraw; |
SkASSERT(NULL == fPicture); |
SkASSERT(NULL == fCanvas.get()); |
@@ -415,8 +419,9 @@ SkString PipePictureRenderer::getConfigNameInternal() { |
void SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath, |
const SkString* mismatchPath, const SkString* inputFilename, |
- bool useChecksumBasedFilenames) { |
- INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames); |
+ bool useChecksumBasedFilenames, bool useMultiPictureDraw) { |
+ INHERITED::init(picture, writePath, mismatchPath, inputFilename, |
+ useChecksumBasedFilenames, useMultiPictureDraw); |
this->buildBBoxHierarchy(); |
} |
@@ -427,7 +432,15 @@ bool SimplePictureRenderer::render(SkBitmap** out) { |
return false; |
} |
- fCanvas->drawPicture(fPicture); |
+ if (fUseMultiPictureDraw) { |
+ SkMultiPictureDraw mpd; |
+ |
+ mpd.add(fCanvas, fPicture); |
+ |
+ mpd.draw(); |
+ } else { |
+ fCanvas->drawPicture(fPicture); |
+ } |
fCanvas->flush(); |
if (out) { |
*out = SkNEW(SkBitmap); |
@@ -467,7 +480,7 @@ TiledPictureRenderer::TiledPictureRenderer() |
void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath, |
const SkString* mismatchPath, const SkString* inputFilename, |
- bool useChecksumBasedFilenames) { |
+ bool useChecksumBasedFilenames, bool useMultiPictureDraw) { |
SkASSERT(pict); |
SkASSERT(0 == fTileRects.count()); |
if (NULL == pict || fTileRects.count() != 0) { |
@@ -481,6 +494,7 @@ void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath |
this->CopyString(&fMismatchPath, mismatchPath); |
this->CopyString(&fInputFilename, inputFilename); |
fUseChecksumBasedFilenames = useChecksumBasedFilenames; |
+ fUseMultiPictureDraw = useMultiPictureDraw; |
this->buildBBoxHierarchy(); |
if (fTileWidthPercentage > 0) { |
@@ -519,10 +533,8 @@ void TiledPictureRenderer::setupTiles() { |
// Only count tiles in the X direction on the first pass. |
fTilesX++; |
} |
- *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), |
- SkIntToScalar(tile_y_start), |
- SkIntToScalar(fTileWidth), |
- SkIntToScalar(fTileHeight)); |
+ *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start, |
+ fTileWidth, fTileHeight); |
} |
} |
} |
@@ -575,10 +587,8 @@ void TiledPictureRenderer::setupPowerOf2Tiles() { |
// Only count tiles in the X direction on the first pass. |
fTilesX++; |
} |
- *fTileRects.append() = SkRect::MakeXYWH(SkIntToScalar(tile_x_start), |
- SkIntToScalar(tile_y_start), |
- SkIntToScalar(current_width), |
- SkIntToScalar(fTileHeight)); |
+ *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start, |
+ current_width, fTileHeight); |
tile_x_start += current_width; |
} |
@@ -594,13 +604,13 @@ void TiledPictureRenderer::setupPowerOf2Tiles() { |
* is called. |
*/ |
static void draw_tile_to_canvas(SkCanvas* canvas, |
- const SkRect& tileRect, |
+ const SkIRect& tileRect, |
const SkPicture* picture) { |
int saveCount = canvas->save(); |
// Translate so that we draw the correct portion of the picture. |
// Perform a postTranslate so that the scaleFactor does not interfere with the positioning. |
SkMatrix mat(canvas->getTotalMatrix()); |
- mat.postTranslate(-tileRect.fLeft, -tileRect.fTop); |
+ mat.postTranslate(-SkIntToScalar(tileRect.fLeft), -SkIntToScalar(tileRect.fTop)); |
canvas->setMatrix(mat); |
canvas->drawPicture(picture); |
canvas->restoreToCount(saveCount); |
@@ -643,6 +653,27 @@ void TiledPictureRenderer::drawCurrentTile() { |
draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture); |
} |
+bool TiledPictureRenderer::postRender(SkCanvas* canvas, const SkIRect& tileRect, |
+ SkBitmap* tempBM, SkBitmap** out, |
+ int tileNumber) { |
+ bool success = true; |
+ |
+ if (fEnableWrites) { |
+ success &= write(canvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr, |
+ fUseChecksumBasedFilenames, &tileNumber); |
+ } |
+ if (out) { |
+ if (canvas->readPixels(tempBM, 0, 0)) { |
+ // Add this tile to the entire bitmap. |
+ bitmapCopyAtOffset(*tempBM, *out, tileRect.left(), tileRect.top()); |
+ } else { |
+ success = false; |
+ } |
+ } |
+ |
+ return success; |
+} |
+ |
bool TiledPictureRenderer::render(SkBitmap** out) { |
SkASSERT(fPicture != NULL); |
if (NULL == fPicture) { |
@@ -650,29 +681,59 @@ bool TiledPictureRenderer::render(SkBitmap** out) { |
} |
SkBitmap bitmap; |
- if (out){ |
+ if (out) { |
*out = SkNEW(SkBitmap); |
setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), |
SkScalarCeilToInt(fPicture->cullRect().height())); |
setup_bitmap(&bitmap, fTileWidth, fTileHeight); |
} |
bool success = true; |
- for (int i = 0; i < fTileRects.count(); ++i) { |
- draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture); |
- if (fEnableWrites) { |
- success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr, |
- fUseChecksumBasedFilenames, &i); |
+ |
+ if (fUseMultiPictureDraw) { |
+ SkMultiPictureDraw mpd; |
+ SkTDArray<SkSurface*> surfaces; |
+ surfaces.setReserve(fTileRects.count()); |
+ |
+ // Create a separate SkSurface/SkCanvas for each tile along with a |
+ // translated version of the skp (to mimic Chrome's behavior) and |
+ // feed all such pairs to the MultiPictureDraw. |
+ for (int i = 0; i < fTileRects.count(); ++i) { |
+ SkImageInfo ii = fCanvas->imageInfo().makeWH(fTileRects[i].width(), |
+ fTileRects[i].height()); |
+ *surfaces.append() = fCanvas->newSurface(ii); |
+ surfaces[i]->getCanvas()->setMatrix(fCanvas->getTotalMatrix()); |
+ |
+ SkPictureRecorder recorder; |
+ SkCanvas* c = recorder.beginRecording(SkIntToScalar(fTileRects[i].width()), |
+ SkIntToScalar(fTileRects[i].height())); |
+ c->save(); |
+ SkMatrix mat; |
+ mat.setTranslate(-SkIntToScalar(fTileRects[i].fLeft), |
+ -SkIntToScalar(fTileRects[i].fTop)); |
+ c->setMatrix(mat); |
+ c->drawPicture(fPicture); |
+ c->restore(); |
+ |
+ SkAutoTUnref<SkPicture> xlatedPicture(recorder.endRecording()); |
+ |
+ mpd.add(surfaces[i]->getCanvas(), xlatedPicture); |
} |
- if (out) { |
- if (fCanvas->readPixels(&bitmap, 0, 0)) { |
- // Add this tile to the entire bitmap. |
- bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i].left()), |
- SkScalarFloorToInt(fTileRects[i].top())); |
- } else { |
- success = false; |
- } |
+ |
+ // Render all the buffered SkCanvases/SkPictures |
+ mpd.draw(); |
+ |
+ // Sort out the results and cleanup the allocated surfaces |
+ for (int i = 0; i < fTileRects.count(); ++i) { |
+ success &= this->postRender(surfaces[i]->getCanvas(), fTileRects[i], &bitmap, out, i); |
+ surfaces[i]->unref(); |
+ } |
+ } else { |
+ for (int i = 0; i < fTileRects.count(); ++i) { |
+ draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture); |
+ success &= this->postRender(fCanvas, fTileRects[i], &bitmap, out, i); |
} |
} |
+ |
return success; |
} |