aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/core.gypi1
-rw-r--r--include/core/SkCanvas.h2
-rw-r--r--include/core/SkImage.h2
-rw-r--r--include/core/SkPicture.h16
-rw-r--r--include/core/SkShader.h3
-rw-r--r--samplecode/SampleApp.cpp4
-rw-r--r--src/core/SkBitmapProcShader.cpp6
-rw-r--r--src/core/SkBitmapProcShader.h1
-rw-r--r--src/core/SkCanvas.cpp4
-rw-r--r--src/core/SkPicturePreroll.cpp162
-rw-r--r--src/core/SkPictureShader.cpp4
-rw-r--r--src/core/SkPictureShader.h1
-rw-r--r--src/image/SkImage.cpp4
-rw-r--r--src/image/SkImage_Base.h2
-rw-r--r--src/image/SkImage_Raster.cpp8
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();
}
+