Index: tools/PictureRenderer.cpp |
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp |
deleted file mode 100644 |
index c550b6eefb2634af94891e5500f04c21c11c0162..0000000000000000000000000000000000000000 |
--- a/tools/PictureRenderer.cpp |
+++ /dev/null |
@@ -1,739 +0,0 @@ |
-/* |
- * Copyright 2012 Google Inc. |
- * |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-#include "PictureRenderer.h" |
-#include "picture_utils.h" |
-#include "SamplePipeControllers.h" |
-#include "SkBitmapHasher.h" |
-#include "SkCanvas.h" |
-#include "SkData.h" |
-#include "SkDevice.h" |
-#include "SkDiscardableMemoryPool.h" |
-#include "SkGPipe.h" |
-#if SK_SUPPORT_GPU |
-#include "gl/GrGLDefines.h" |
-#include "SkGpuDevice.h" |
-#endif |
-#include "SkGraphics.h" |
-#include "SkImageEncoder.h" |
-#include "SkMaskFilter.h" |
-#include "SkMatrix.h" |
-#include "SkMultiPictureDraw.h" |
-#include "SkOSFile.h" |
-#include "SkPaintFilterCanvas.h" |
-#include "SkPicture.h" |
-#include "SkPictureRecorder.h" |
-#include "SkPictureUtils.h" |
-#include "SkPixelRef.h" |
-#include "SkPixelSerializer.h" |
-#include "SkScalar.h" |
-#include "SkStream.h" |
-#include "SkString.h" |
-#include "SkSurface.h" |
-#include "SkTemplates.h" |
-#include "SkTDArray.h" |
-#include "SkThreadUtils.h" |
-#include "SkTypes.h" |
-#include "sk_tool_utils.h" |
- |
-static inline SkScalar scalar_log2(SkScalar x) { |
- static const SkScalar log2_conversion_factor = SkScalarInvert(SkScalarLog(2)); |
- |
- return SkScalarLog(x) * log2_conversion_factor; |
-} |
- |
-namespace sk_tools { |
- |
-enum { |
- kDefaultTileWidth = 256, |
- kDefaultTileHeight = 256 |
-}; |
- |
-void PictureRenderer::init(const SkPicture* pict, |
- const SkString* writePath, |
- const SkString* mismatchPath, |
- const SkString* inputFilename, |
- bool useChecksumBasedFilenames, |
- bool useMultiPictureDraw) { |
- this->CopyString(&fWritePath, writePath); |
- this->CopyString(&fMismatchPath, mismatchPath); |
- this->CopyString(&fInputFilename, inputFilename); |
- fUseChecksumBasedFilenames = useChecksumBasedFilenames; |
- fUseMultiPictureDraw = useMultiPictureDraw; |
- |
- SkASSERT(nullptr == fPicture); |
- SkASSERT(nullptr == fCanvas.get()); |
- if (fPicture || fCanvas.get()) { |
- return; |
- } |
- |
- SkASSERT(pict != nullptr); |
- if (nullptr == pict) { |
- return; |
- } |
- |
- fPicture.reset(SkRef(pict)); |
- fCanvas.reset(this->setupCanvas()); |
-} |
- |
-void PictureRenderer::CopyString(SkString* dest, const SkString* src) { |
- if (src) { |
- dest->set(*src); |
- } else { |
- dest->reset(); |
- } |
-} |
- |
-class FlagsFilterCanvas : public SkPaintFilterCanvas { |
-public: |
- FlagsFilterCanvas(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* flags) |
- : INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height()) |
- , fFlags(flags) { |
- this->addCanvas(canvas); |
- } |
- |
-protected: |
- void onFilterPaint(SkPaint* paint, Type t) const override { |
- paint->setFlags(paint->getFlags() & ~fFlags[t] & SkPaint::kAllFlags); |
- if (PictureRenderer::kMaskFilter_DrawFilterFlag & fFlags[t]) { |
- SkMaskFilter* maskFilter = paint->getMaskFilter(); |
- if (maskFilter) { |
- paint->setMaskFilter(nullptr); |
- } |
- } |
- if (PictureRenderer::kHinting_DrawFilterFlag & fFlags[t]) { |
- paint->setHinting(SkPaint::kNo_Hinting); |
- } else if (PictureRenderer::kSlightHinting_DrawFilterFlag & fFlags[t]) { |
- paint->setHinting(SkPaint::kSlight_Hinting); |
- } |
- } |
- |
-private: |
- const PictureRenderer::DrawFilterFlags* fFlags; |
- |
- typedef SkPaintFilterCanvas INHERITED; |
-}; |
- |
-SkCanvas* PictureRenderer::setupCanvas() { |
- const int width = this->getViewWidth(); |
- const int height = this->getViewHeight(); |
- return this->setupCanvas(width, height); |
-} |
- |
-SkCanvas* PictureRenderer::setupCanvas(int width, int height) { |
- SkAutoTUnref<SkCanvas> canvas; |
- |
- switch(fDeviceType) { |
- case kBitmap_DeviceType: { |
- SkBitmap bitmap; |
- sk_tools::setup_bitmap(&bitmap, width, height); |
- canvas.reset(new SkCanvas(bitmap)); |
- } |
- break; |
-#if SK_SUPPORT_GPU |
-#if SK_ANGLE |
- case kAngle_DeviceType: |
- // fall through |
-#endif |
-#if SK_COMMAND_BUFFER |
- case kCommandBuffer_DeviceType: |
- // fall through |
-#endif |
-#if SK_MESA |
- case kMesa_DeviceType: |
- // fall through |
-#endif |
- case kGPU_DeviceType: |
- case kNVPR_DeviceType: { |
- SkAutoTUnref<GrSurface> target; |
- if (fGrContext) { |
- // create a render target to back the device |
- GrSurfaceDesc desc; |
- desc.fConfig = kSkia8888_GrPixelConfig; |
- desc.fFlags = kRenderTarget_GrSurfaceFlag; |
- desc.fWidth = width; |
- desc.fHeight = height; |
- desc.fSampleCnt = fSampleCount; |
- target.reset(fGrContext->textureProvider()->createTexture(desc, false, nullptr, 0)); |
- } |
- |
- uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0; |
- SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); |
- SkAutoTUnref<SkGpuDevice> device( |
- SkGpuDevice::Create(target->asRenderTarget(), &props, |
- SkGpuDevice::kUninit_InitContents)); |
- if (!device) { |
- return nullptr; |
- } |
- canvas.reset(new SkCanvas(device)); |
- break; |
- } |
-#endif |
- default: |
- SkASSERT(0); |
- return nullptr; |
- } |
- |
- if (fHasDrawFilters) { |
- if (fDrawFilters[0] & PictureRenderer::kAAClip_DrawFilterFlag) { |
- canvas->setAllowSoftClip(false); |
- } |
- |
- canvas.reset(new FlagsFilterCanvas(canvas.get(), fDrawFilters)); |
- } |
- |
- this->scaleToScaleFactor(canvas); |
- |
- // Pictures often lie about their extent (i.e., claim to be 100x100 but |
- // only ever draw to 90x100). Clear here so the undrawn portion will have |
- // a consistent color |
- canvas->clear(SK_ColorTRANSPARENT); |
- return canvas.detach(); |
-} |
- |
-void PictureRenderer::scaleToScaleFactor(SkCanvas* canvas) { |
- SkASSERT(canvas != nullptr); |
- if (fScaleFactor != SK_Scalar1) { |
- canvas->scale(fScaleFactor, fScaleFactor); |
- } |
-} |
- |
-void PictureRenderer::end() { |
- this->resetState(true); |
- fPicture.reset(nullptr); |
- fCanvas.reset(nullptr); |
-} |
- |
-int PictureRenderer::getViewWidth() { |
- SkASSERT(fPicture != nullptr); |
- int width = SkScalarCeilToInt(fPicture->cullRect().width() * fScaleFactor); |
- if (fViewport.width() > 0) { |
- width = SkMin32(width, fViewport.width()); |
- } |
- return width; |
-} |
- |
-int PictureRenderer::getViewHeight() { |
- SkASSERT(fPicture != nullptr); |
- int height = SkScalarCeilToInt(fPicture->cullRect().height() * fScaleFactor); |
- if (fViewport.height() > 0) { |
- height = SkMin32(height, fViewport.height()); |
- } |
- return height; |
-} |
- |
-/** Converts fPicture to a picture that uses a BBoxHierarchy. |
- * PictureRenderer subclasses that are used to test picture playback |
- * should call this method during init. |
- */ |
-void PictureRenderer::buildBBoxHierarchy() { |
- SkASSERT(fPicture); |
- if (kNone_BBoxHierarchyType != fBBoxHierarchyType && fPicture) { |
- SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); |
- SkPictureRecorder recorder; |
- uint32_t flags = this->recordFlags(); |
- if (fUseMultiPictureDraw) { |
- flags |= SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; |
- } |
- SkCanvas* canvas = recorder.beginRecording(fPicture->cullRect().width(), |
- fPicture->cullRect().height(), |
- factory.get(), |
- flags); |
- fPicture->playback(canvas); |
- fPicture.reset(recorder.endRecording()); |
- } |
-} |
- |
-void PictureRenderer::resetState(bool callFinish) { |
-#if SK_SUPPORT_GPU |
- SkGLContext* glContext = this->getGLContext(); |
- if (nullptr == glContext) { |
- SkASSERT(kBitmap_DeviceType == fDeviceType); |
- return; |
- } |
- |
- fGrContext->flush(); |
- glContext->swapBuffers(); |
- if (callFinish) { |
- SK_GL(*glContext, Finish()); |
- } |
-#endif |
-} |
- |
-void PictureRenderer::purgeTextures() { |
- SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool(); |
- |
- pool->dumpPool(); |
- |
-#if SK_SUPPORT_GPU |
- SkGLContext* glContext = this->getGLContext(); |
- if (nullptr == glContext) { |
- SkASSERT(kBitmap_DeviceType == fDeviceType); |
- return; |
- } |
- |
- // resetState should've already done this |
- fGrContext->flush(); |
- |
- fGrContext->purgeAllUnlockedResources(); |
-#endif |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) { |
- // defer the canvas setup until the render step |
- return nullptr; |
-} |
- |
-bool RecordPictureRenderer::render(SkBitmap** out) { |
- SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); |
- SkPictureRecorder recorder; |
- SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(this->getViewWidth()), |
- SkIntToScalar(this->getViewHeight()), |
- factory.get(), |
- this->recordFlags()); |
- this->scaleToScaleFactor(canvas); |
- fPicture->playback(canvas); |
- SkAutoTUnref<SkPicture> picture(recorder.endRecording()); |
- if (!fWritePath.isEmpty()) { |
- // Record the new picture as a new SKP with PNG encoded bitmaps. |
- SkString skpPath = SkOSPath::Join(fWritePath.c_str(), fInputFilename.c_str()); |
- SkFILEWStream stream(skpPath.c_str()); |
- sk_tool_utils::PngPixelSerializer serializer; |
- picture->serialize(&stream, &serializer); |
- return true; |
- } |
- return false; |
-} |
- |
-SkString RecordPictureRenderer::getConfigNameInternal() { |
- return SkString("record"); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-bool PipePictureRenderer::render(SkBitmap** out) { |
- SkASSERT(fCanvas.get() != nullptr); |
- SkASSERT(fPicture != nullptr); |
- if (nullptr == fCanvas.get() || nullptr == fPicture) { |
- return false; |
- } |
- |
- PipeController pipeController(fCanvas.get()); |
- SkGPipeWriter writer; |
- SkCanvas* pipeCanvas = writer.startRecording(&pipeController); |
- pipeCanvas->drawPicture(fPicture); |
- writer.endRecording(); |
- fCanvas->flush(); |
- if (out) { |
- *out = new SkBitmap; |
- setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), |
- SkScalarCeilToInt(fPicture->cullRect().height())); |
- fCanvas->readPixels(*out, 0, 0); |
- } |
- return true; |
-} |
- |
-SkString PipePictureRenderer::getConfigNameInternal() { |
- return SkString("pipe"); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-void SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath, |
- const SkString* mismatchPath, const SkString* inputFilename, |
- bool useChecksumBasedFilenames, bool useMultiPictureDraw) { |
- INHERITED::init(picture, writePath, mismatchPath, inputFilename, |
- useChecksumBasedFilenames, useMultiPictureDraw); |
- this->buildBBoxHierarchy(); |
-} |
- |
-bool SimplePictureRenderer::render(SkBitmap** out) { |
- SkASSERT(fCanvas.get() != nullptr); |
- SkASSERT(fPicture); |
- if (nullptr == fCanvas.get() || nullptr == fPicture) { |
- return false; |
- } |
- |
- if (fUseMultiPictureDraw) { |
- SkMultiPictureDraw mpd; |
- |
- mpd.add(fCanvas, fPicture); |
- |
- mpd.draw(); |
- } else { |
- fCanvas->drawPicture(fPicture); |
- } |
- fCanvas->flush(); |
- if (out) { |
- *out = new SkBitmap; |
- setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), |
- SkScalarCeilToInt(fPicture->cullRect().height())); |
- fCanvas->readPixels(*out, 0, 0); |
- } |
- return true; |
-} |
- |
-SkString SimplePictureRenderer::getConfigNameInternal() { |
- return SkString("simple"); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-#if SK_SUPPORT_GPU |
-TiledPictureRenderer::TiledPictureRenderer(const GrContextOptions& opts) |
- : INHERITED(opts) |
- , fTileWidth(kDefaultTileWidth) |
-#else |
-TiledPictureRenderer::TiledPictureRenderer() |
- : fTileWidth(kDefaultTileWidth) |
-#endif |
- , fTileHeight(kDefaultTileHeight) |
- , fTileWidthPercentage(0.0) |
- , fTileHeightPercentage(0.0) |
- , fTileMinPowerOf2Width(0) |
- , fCurrentTileOffset(-1) |
- , fTilesX(0) |
- , fTilesY(0) { } |
- |
-void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath, |
- const SkString* mismatchPath, const SkString* inputFilename, |
- bool useChecksumBasedFilenames, bool useMultiPictureDraw) { |
- SkASSERT(pict); |
- SkASSERT(0 == fTileRects.count()); |
- if (nullptr == pict || fTileRects.count() != 0) { |
- return; |
- } |
- |
- // Do not call INHERITED::init(), which would create a (potentially large) canvas which is not |
- // used by bench_pictures. |
- fPicture.reset(SkRef(pict)); |
- this->CopyString(&fWritePath, writePath); |
- this->CopyString(&fMismatchPath, mismatchPath); |
- this->CopyString(&fInputFilename, inputFilename); |
- fUseChecksumBasedFilenames = useChecksumBasedFilenames; |
- fUseMultiPictureDraw = useMultiPictureDraw; |
- this->buildBBoxHierarchy(); |
- |
- if (fTileWidthPercentage > 0) { |
- fTileWidth = SkScalarCeilToInt(float(fTileWidthPercentage * fPicture->cullRect().width() / 100)); |
- } |
- if (fTileHeightPercentage > 0) { |
- fTileHeight = SkScalarCeilToInt(float(fTileHeightPercentage * fPicture->cullRect().height() / 100)); |
- } |
- |
- if (fTileMinPowerOf2Width > 0) { |
- this->setupPowerOf2Tiles(); |
- } else { |
- this->setupTiles(); |
- } |
- fCanvas.reset(this->setupCanvas(fTileWidth, fTileHeight)); |
- // Initialize to -1 so that the first call to nextTile will set this up to draw tile 0 on the |
- // first call to drawCurrentTile. |
- fCurrentTileOffset = -1; |
-} |
- |
-void TiledPictureRenderer::end() { |
- fTileRects.reset(); |
- this->INHERITED::end(); |
-} |
- |
-void TiledPictureRenderer::setupTiles() { |
- // Only use enough tiles to cover the viewport |
- const int width = this->getViewWidth(); |
- const int height = this->getViewHeight(); |
- |
- fTilesX = fTilesY = 0; |
- for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) { |
- fTilesY++; |
- for (int tile_x_start = 0; tile_x_start < width; tile_x_start += fTileWidth) { |
- if (0 == tile_y_start) { |
- // Only count tiles in the X direction on the first pass. |
- fTilesX++; |
- } |
- *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start, |
- fTileWidth, fTileHeight); |
- } |
- } |
-} |
- |
-bool TiledPictureRenderer::tileDimensions(int &x, int &y) { |
- if (fTileRects.count() == 0 || nullptr == fPicture) { |
- return false; |
- } |
- x = fTilesX; |
- y = fTilesY; |
- return true; |
-} |
- |
-// The goal of the powers of two tiles is to minimize the amount of wasted tile |
-// space in the width-wise direction and then minimize the number of tiles. The |
-// constraints are that every tile must have a pixel width that is a power of |
-// two and also be of some minimal width (that is also a power of two). |
-// |
-// This is solved by first taking our picture size and rounding it up to the |
-// multiple of the minimal width. The binary representation of this rounded |
-// value gives us the tiles we need: a bit of value one means we need a tile of |
-// that size. |
-void TiledPictureRenderer::setupPowerOf2Tiles() { |
- // Only use enough tiles to cover the viewport |
- const int width = this->getViewWidth(); |
- const int height = this->getViewHeight(); |
- |
- int rounded_value = width; |
- if (width % fTileMinPowerOf2Width != 0) { |
- rounded_value = width - (width % fTileMinPowerOf2Width) + fTileMinPowerOf2Width; |
- } |
- |
- int num_bits = SkScalarCeilToInt(scalar_log2(SkIntToScalar(width))); |
- int largest_possible_tile_size = 1 << num_bits; |
- |
- fTilesX = fTilesY = 0; |
- // The tile height is constant for a particular picture. |
- for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) { |
- fTilesY++; |
- int tile_x_start = 0; |
- int current_width = largest_possible_tile_size; |
- // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough |
- // to draw each tile. |
- fTileWidth = current_width; |
- |
- while (current_width >= fTileMinPowerOf2Width) { |
- // It is very important this is a bitwise AND. |
- if (current_width & rounded_value) { |
- if (0 == tile_y_start) { |
- // Only count tiles in the X direction on the first pass. |
- fTilesX++; |
- } |
- *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start, |
- current_width, fTileHeight); |
- tile_x_start += current_width; |
- } |
- |
- current_width >>= 1; |
- } |
- } |
-} |
- |
-/** |
- * Draw the specified picture to the canvas translated to rectangle provided, so that this mini |
- * canvas represents the rectangle's portion of the overall picture. |
- * Saves and restores so that the initial clip and matrix return to their state before this function |
- * is called. |
- */ |
-static void draw_tile_to_canvas(SkCanvas* canvas, |
- 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(-SkIntToScalar(tileRect.fLeft), -SkIntToScalar(tileRect.fTop)); |
- canvas->setMatrix(mat); |
- canvas->clipRect(SkRect::Make(tileRect)); |
- canvas->clear(SK_ColorTRANSPARENT); // Not every picture covers the entirety of every tile |
- canvas->drawPicture(picture); |
- canvas->restoreToCount(saveCount); |
- canvas->flush(); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-/** |
- * Copies the entirety of the src bitmap (typically a tile) into a portion of the dst bitmap. |
- * If the src bitmap is too large to fit within the dst bitmap after the x and y |
- * offsets have been applied, any excess will be ignored (so only the top-left portion of the |
- * src bitmap will be copied). |
- * |
- * @param src source bitmap |
- * @param dst destination bitmap |
- * @param xOffset x-offset within destination bitmap |
- * @param yOffset y-offset within destination bitmap |
- */ |
-static void bitmapCopyAtOffset(const SkBitmap& src, SkBitmap* dst, |
- int xOffset, int yOffset) { |
- for (int y = 0; y <src.height() && y + yOffset < dst->height() ; y++) { |
- for (int x = 0; x < src.width() && x + xOffset < dst->width() ; x++) { |
- *dst->getAddr32(xOffset + x, yOffset + y) = *src.getAddr32(x, y); |
- } |
- } |
-} |
- |
-bool TiledPictureRenderer::nextTile(int &i, int &j) { |
- if (++fCurrentTileOffset < fTileRects.count()) { |
- i = fCurrentTileOffset % fTilesX; |
- j = fCurrentTileOffset / fTilesX; |
- return true; |
- } |
- return false; |
-} |
- |
-void TiledPictureRenderer::drawCurrentTile() { |
- SkASSERT(fCurrentTileOffset >= 0 && fCurrentTileOffset < fTileRects.count()); |
- 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 (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 != nullptr); |
- if (nullptr == fPicture) { |
- return false; |
- } |
- |
- SkBitmap bitmap; |
- if (out) { |
- *out = new SkBitmap; |
- setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()), |
- SkScalarCeilToInt(fPicture->cullRect().height())); |
- setup_bitmap(&bitmap, fTileWidth, fTileHeight); |
- } |
- bool success = true; |
- |
- 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; |
- SkRTreeFactory bbhFactory; |
- |
- SkCanvas* c = recorder.beginRecording(SkIntToScalar(fTileRects[i].width()), |
- SkIntToScalar(fTileRects[i].height()), |
- &bbhFactory, |
- SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag); |
- 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); |
- } |
- |
- // 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; |
-} |
- |
-SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) { |
- SkCanvas* canvas = this->INHERITED::setupCanvas(width, height); |
- SkASSERT(fPicture); |
- // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This |
- // is mostly important for tiles on the right and bottom edges as they may go over this area and |
- // the picture may have some commands that draw outside of this area and so should not actually |
- // be written. |
- // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set |
- // by INHERITED::setupCanvas. |
- SkRegion clipRegion; |
- clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight()); |
- canvas->clipRegion(clipRegion); |
- return canvas; |
-} |
- |
-SkString TiledPictureRenderer::getConfigNameInternal() { |
- SkString name; |
- if (fTileMinPowerOf2Width > 0) { |
- name.append("pow2tile_"); |
- name.appendf("%i", fTileMinPowerOf2Width); |
- } else { |
- name.append("tile_"); |
- if (fTileWidthPercentage > 0) { |
- name.appendf("%.f%%", fTileWidthPercentage); |
- } else { |
- name.appendf("%i", fTileWidth); |
- } |
- } |
- name.append("x"); |
- if (fTileHeightPercentage > 0) { |
- name.appendf("%.f%%", fTileHeightPercentage); |
- } else { |
- name.appendf("%i", fTileHeight); |
- } |
- return name; |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-void PlaybackCreationRenderer::setup() { |
- SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); |
- fRecorder.reset(new SkPictureRecorder); |
- SkCanvas* canvas = fRecorder->beginRecording(SkIntToScalar(this->getViewWidth()), |
- SkIntToScalar(this->getViewHeight()), |
- factory.get(), |
- this->recordFlags()); |
- this->scaleToScaleFactor(canvas); |
- canvas->drawPicture(fPicture); |
-} |
- |
-bool PlaybackCreationRenderer::render(SkBitmap** out) { |
- fPicture.reset(fRecorder->endRecording()); |
- // Since this class does not actually render, return false. |
- return false; |
-} |
- |
-SkString PlaybackCreationRenderer::getConfigNameInternal() { |
- return SkString("playback_creation"); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////////////////////// |
-// SkPicture variants for each BBoxHierarchy type |
- |
-SkBBHFactory* PictureRenderer::getFactory() { |
- switch (fBBoxHierarchyType) { |
- case kNone_BBoxHierarchyType: |
- return nullptr; |
- case kRTree_BBoxHierarchyType: |
- return new SkRTreeFactory; |
- } |
- SkASSERT(0); // invalid bbhType |
- return nullptr; |
-} |
- |
-} // namespace sk_tools |