initial preroll api

BUG=skia:

Review URL: https://codereview.chromium.org/855473002
This commit is contained in:
reed 2015-01-25 10:33:58 -08:00 committed by Commit bot
parent dadbb357c8
commit 96a857ef5a
15 changed files with 217 additions and 3 deletions

View File

@ -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',

View File

@ -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.

View File

@ -131,6 +131,8 @@ public:
*/
SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const;
void preroll() const;
const char* toString(SkString*) const;
/**

View File

@ -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

View File

@ -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;
}

View File

@ -1339,6 +1339,10 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
if (kPicture_DeviceType == fDeviceType) {
SkAutoTUnref<const SkPicture> picture(fRecorder.endRecording());
if (true) {
picture->preroll(NULL, NULL, NULL, NULL);
}
if (true) {
this->installDrawFilter(orig);

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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,

View File

@ -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*);

View File

@ -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) {

View File

@ -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;

View File

@ -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();
}