diff options
-rw-r--r-- | gyp/core.gypi | 1 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 2 | ||||
-rw-r--r-- | include/core/SkImage.h | 2 | ||||
-rw-r--r-- | include/core/SkPicture.h | 16 | ||||
-rw-r--r-- | include/core/SkShader.h | 3 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 4 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 6 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.h | 1 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 4 | ||||
-rw-r--r-- | src/core/SkPicturePreroll.cpp | 162 | ||||
-rw-r--r-- | src/core/SkPictureShader.cpp | 4 | ||||
-rw-r--r-- | src/core/SkPictureShader.h | 1 | ||||
-rw-r--r-- | src/image/SkImage.cpp | 4 | ||||
-rw-r--r-- | src/image/SkImage_Base.h | 2 | ||||
-rw-r--r-- | src/image/SkImage_Raster.cpp | 8 |
15 files changed, 217 insertions, 3 deletions
diff --git a/gyp/core.gypi b/gyp/core.gypi index 48228515fb..e7567281a0 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -145,6 +145,7 @@ '<(skia_src_path)/core/SkPictureFlat.h', '<(skia_src_path)/core/SkPicturePlayback.cpp', '<(skia_src_path)/core/SkPicturePlayback.h', + '<(skia_src_path)/core/SkPicturePreroll.cpp', '<(skia_src_path)/core/SkPictureRecord.cpp', '<(skia_src_path)/core/SkPictureRecord.h', '<(skia_src_path)/core/SkPictureRecorder.cpp', diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 4e7ed3066e..3eecaf760a 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -87,7 +87,7 @@ public: * by any device/pixels. Typically this use used by subclasses who handle * the draw calls in some other way. */ - SkCanvas(int width, int height); + SkCanvas(int width, int height, const SkSurfaceProps* = NULL); /** Construct a canvas with the specified device to draw into. diff --git a/include/core/SkImage.h b/include/core/SkImage.h index b0587b2c3a..f59042cada 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -131,6 +131,8 @@ public: */ SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const; + void preroll() const; + const char* toString(SkString*) const; /** diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 5b2f7a99f7..5a48476db0 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -171,6 +171,22 @@ public: */ bool willPlayBackBitmaps() const; + /** + * This is a general hint that the picture will (soon) be drawn into a SkCanvas with + * corresponding attributes (e.g. clip, matrix, props). No drawing occurs, but some + * expensive operations may be run (e.g. image decoding). + * + * Any of the parameters may be NULL. + * + * @param srcBounds If not NULL, this is the subset of the picture (in the same coordinates + * as the picture's bounds) that preroll() should focus on. + * @param initialMatrix If not NULL, this is the initialMatrix that is expected when the + * picture is actually drawn. + * @param props If not NULL, these are the expected props when the picture is actually drawn. + */ + void preroll(const SkRect* srcBounds, const SkMatrix* initialMatrix, const SkSurfaceProps*, + void* gpuCacheAccessor) const; + /** Return true if the SkStream/Buffer represents a serialized picture, and fills out SkPictInfo. After this function returns, the data source is not rewound so it will have to be manually reset before passing to diff --git a/include/core/SkShader.h b/include/core/SkShader.h index f8de276c7b..1ae531e2e5 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -478,6 +478,8 @@ public: */ virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const; + void preroll() const { this->onPreroll(); } + SK_TO_STRING_VIRT() SK_DEFINE_FLATTENABLE_TYPE(SkShader) @@ -492,6 +494,7 @@ protected: */ virtual Context* onCreateContext(const ContextRec&, void* storage) const; + virtual void onPreroll() const {} virtual bool onAsLuminanceColor(SkColor*) const { return false; } diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 105976d2f4..aa2130e8f0 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -1340,6 +1340,10 @@ void SampleWindow::afterChildren(SkCanvas* orig) { SkAutoTUnref<const SkPicture> picture(fRecorder.endRecording()); if (true) { + picture->preroll(NULL, NULL, NULL, NULL); + } + + if (true) { this->installDrawFilter(orig); if (true) { diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 456e0d4920..e6ed1136c0 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -112,6 +112,12 @@ size_t SkBitmapProcShader::contextSize() const { return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); } +void SkBitmapProcShader::onPreroll() const { + SkBitmap bm(fRawBitmap); + bm.lockPixels(); + bm.unlockPixels(); +} + SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state) : INHERITED(shader, rec) diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index f73d56f2fb..dc361542da 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -57,6 +57,7 @@ public: protected: void flatten(SkWriteBuffer&) const SK_OVERRIDE; Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE; + void onPreroll() const SK_OVERRIDE; SkBitmap fRawBitmap; // experimental for RLE encoding uint8_t fTileModeX, fTileModeY; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 13b84e7f0f..5b37e08b30 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -482,9 +482,9 @@ private: typedef SkBitmapDevice INHERITED; }; -SkCanvas::SkCanvas(int width, int height) +SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) - , fProps(SkSurfaceProps::kLegacyFontHost_InitType) + , fProps(SkSurfacePropsCopyOrDefault(props)) { inc_canvas(); diff --git a/src/core/SkPicturePreroll.cpp b/src/core/SkPicturePreroll.cpp new file mode 100644 index 0000000000..b0a4b17f56 --- /dev/null +++ b/src/core/SkPicturePreroll.cpp @@ -0,0 +1,162 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkCanvas.h" +#include "SkPicture.h" + +class SkPrerollCanvas : public SkCanvas { +public: + SkPrerollCanvas(int width, int height, const SkSurfaceProps* props) + : SkCanvas(width, height, props) + {} + +protected: + void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawText(const void*, size_t, SkScalar, SkScalar, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, + const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawTextOnPath(const void*, size_t, const SkPath&, const SkMatrix*, + const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkXfermode*, + const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPaint(const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawRect(const SkRect&, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint& paint) { + this->handlePaint(paint); + } + + void onDrawVertices(VertexMode, int, const SkPoint[], const SkPoint[], const SkColor[], + SkXfermode*, const uint16_t[], int, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawPath(const SkPath&, const SkPaint& paint) SK_OVERRIDE { + this->handlePaint(paint); + } + + void onDrawImage(const SkImage* image, SkScalar, SkScalar, const SkPaint* paint) SK_OVERRIDE { + this->handleImage(image); + if (paint) { + this->handlePaint(*paint); + } + } + + void onDrawImageRect(const SkImage* image, const SkRect*, const SkRect&, + const SkPaint* paint) SK_OVERRIDE { + this->handleImage(image); + if (paint) { + this->handlePaint(*paint); + } + } + + void onDrawBitmap(const SkBitmap& bm, SkScalar, SkScalar, const SkPaint* paint) SK_OVERRIDE { + this->handleBitmap(bm); + if (paint) { + this->handlePaint(*paint); + } + } + + void onDrawBitmapRect(const SkBitmap& bm, const SkRect*, const SkRect&, const SkPaint* paint, + DrawBitmapRectFlags) SK_OVERRIDE { + this->handleBitmap(bm); + if (paint) { + this->handlePaint(*paint); + } + } + + void onDrawBitmapNine(const SkBitmap& bm, const SkIRect&, const SkRect&, + const SkPaint* paint) SK_OVERRIDE { + this->handleBitmap(bm); + if (paint) { + this->handlePaint(*paint); + } + } + + void onDrawSprite(const SkBitmap& bm, int, int, const SkPaint* paint) SK_OVERRIDE { + this->handleBitmap(bm); + if (paint) { + this->handlePaint(*paint); + } + } + +private: + void handlePaint(const SkPaint& paint) { + const SkShader* shader = paint.getShader(); + if (shader) { + shader->preroll(); + } + } + + void handleImage(const SkImage* image) { + image->preroll(); + } + + void handleBitmap(const SkBitmap& bitmap) { + SkBitmap bm(bitmap); + bm.lockPixels(); + } + + typedef SkCanvas INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void SkPicture::preroll(const SkRect* srcBounds, const SkMatrix* initialMatrix, + const SkSurfaceProps* props, void* gpuCacheAccessor) const { + SkRect bounds = this->cullRect(); + if (srcBounds && !bounds.intersect(*srcBounds)) { + return; + } + + const SkIRect ibounds = bounds.roundOut(); + if (ibounds.isEmpty()) { + return; + } + + SkPrerollCanvas canvas(ibounds.width(), ibounds.height(), props); + + canvas.translate(-SkIntToScalar(ibounds.left()), -SkIntToScalar(ibounds.top())); + canvas.drawPicture(this, initialMatrix, NULL); +} + diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index 819a0d0ae7..36b55cae66 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -221,6 +221,10 @@ SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* return PictureShaderContext::Create(storage, *this, rec, bitmapShader); } +void SkPictureShader::onPreroll() const { + fPicture->preroll(NULL, NULL, NULL, NULL); +} + ///////////////////////////////////////////////////////////////////////////////////////// SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage, diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h index 8df9f539b8..7b07b851ef 100644 --- a/src/core/SkPictureShader.h +++ b/src/core/SkPictureShader.h @@ -37,6 +37,7 @@ protected: SkPictureShader(SkReadBuffer&); void flatten(SkWriteBuffer&) const SK_OVERRIDE; Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE; + void onPreroll() const SK_OVERRIDE; private: SkPictureShader(const SkPicture*, TileMode, TileMode, const SkMatrix*, const SkRect*); diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 109808842e..35fff1f242 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -118,6 +118,10 @@ SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset, return as_IB(this)->onNewImage(newWidth, newHeight, subset, quality); } +void SkImage::preroll() const { + as_IB(this)->onPreroll(); +} + /////////////////////////////////////////////////////////////////////////////// static bool raster_canvas_supports(const SkImageInfo& info) { diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index 512c80c44b..ca0559ffd0 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -63,6 +63,8 @@ public: virtual SkImage* onNewImage(int newWidth, int newHeight, const SkIRect* subset, SkFilterQuality) const; + virtual void onPreroll() const {} + private: const SkSurfaceProps fProps; diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index 1dd57d6dc2..940d532378 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -58,6 +58,7 @@ public: bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const SK_OVERRIDE; const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE; bool getROPixels(SkBitmap*) const SK_OVERRIDE; + void onPreroll() const SK_OVERRIDE; // exposed for SkSurface_Raster via SkNewImageFromPixelRef SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes, const SkSurfaceProps*); @@ -154,6 +155,12 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst) const { return true; } +void SkImage_Raster::onPreroll() const { + SkBitmap bm(fBitmap); + bm.lockPixels(); + bm.unlockPixels(); +} + /////////////////////////////////////////////////////////////////////////////// SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) { @@ -208,3 +215,4 @@ const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) { bool SkImage_Raster::isOpaque() const { return fBitmap.isOpaque(); } + |