Allow pictures to have a full bounds

This reverts commit 7c4cdd2c5b.

BUG=skia:

Review URL: https://codereview.chromium.org/738083002
This commit is contained in:
reed 2014-11-19 08:04:34 -08:00 committed by Commit bot
parent 7c4cdd2c5b
commit 78e2768897
13 changed files with 84 additions and 44 deletions

View File

@ -9,7 +9,7 @@
#define SkBBHFactory_DEFINED
#include "SkSize.h"
#include "SkPoint.h"
#include "SkRect.h"
class SkBBoxHierarchy;
@ -18,13 +18,13 @@ public:
/**
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
*/
virtual SkBBoxHierarchy* operator()(int width, int height) const = 0;
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0;
virtual ~SkBBHFactory() {};
};
class SK_API SkRTreeFactory : public SkBBHFactory {
public:
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const SK_OVERRIDE;
private:
typedef SkBBHFactory INHERITED;
};
@ -50,7 +50,7 @@ public:
SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { }
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const SK_OVERRIDE;
private:
TileGridInfo fInfo;

View File

@ -1335,7 +1335,7 @@ private:
kDefault_InitFlags = 0,
kConservativeRasterClip_InitFlag = 1 << 0,
};
SkCanvas(int width, int height, InitFlags);
SkCanvas(const SkIRect& bounds, InitFlags);
SkCanvas(SkBaseDevice*, const SkSurfaceProps*, InitFlags);
SkCanvas(const SkBitmap&, const SkSurfaceProps&);

View File

@ -53,6 +53,12 @@ public:
bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
}
SkIRect getGlobalBounds() const {
SkIRect bounds;
this->getGlobalBounds(&bounds);
return bounds;
}
int width() const {
return this->imageInfo().width();
}
@ -366,6 +372,7 @@ private:
friend class SkDeviceFilteredPaint;
friend class SkDeviceImageFilterProxy;
friend class SkDeferredDevice; // for newSurface
friend class SkNoPixelsBitmapDevice;
friend class SkSurface_Raster;

View File

@ -122,15 +122,15 @@ public:
#endif
#ifdef SK_LEGACY_PICTURE_SIZE_API
int width() const { return SkScalarCeilToInt(fCullWidth); }
int height() const { return SkScalarCeilToInt(fCullHeight); }
int width() const { return fCullRect.roundOut().width(); }
int height() const { return fCullRect.roundOut().height(); }
#endif
/** Return the cull rect used when creating this picture: { 0, 0, cullWidth, cullHeight }.
It does not necessarily reflect the bounds of what has been recorded into the picture.
@return the cull rect used to create this picture
*/
const SkRect cullRect() const { return SkRect::MakeWH(fCullWidth, fCullHeight); }
SkRect cullRect() const { return fCullRect; }
/** Return a non-zero, unique value representing the picture. This call is
only valid when not recording. Between a beginRecording/endRecording
@ -260,15 +260,14 @@ private:
static bool IsValidPictInfo(const SkPictInfo& info);
// Takes ownership of the SkRecord, refs the (optional) drawablePicts and BBH.
SkPicture(SkScalar width, SkScalar height, SkRecord*, SkData* drawablePicts,
SkPicture(const SkRect& cullRect, SkRecord*, SkData* drawablePicts,
SkBBoxHierarchy*);
static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*);
static SkPictureData* Backport(const SkRecord&, const SkPictInfo&,
SkPicture const* const drawablePics[], int drawableCount);
const SkScalar fCullWidth;
const SkScalar fCullHeight;
const SkRect fCullRect;
mutable SkAutoTUnref<const AccelData> fAccelData;
mutable SkTDArray<DeletionListener*> fDeletionListeners; // pointers are refed
SkAutoTDelete<SkRecord> fRecord;

View File

@ -44,16 +44,22 @@ public:
};
/** Returns the canvas that records the drawing commands.
@param width the width of the cull rect used when recording this picture.
@param height the height of the cull rect used when recording this picture.
@param bounds the cull rect used when recording this picture. Any drawing the falls outside
of this rect is undefined, and may be drawn or it may not.
@param bbhFactory factory to create desired acceleration structure
@param recordFlags optional flags that control recording.
@return the canvas.
*/
SkCanvas* beginRecording(SkScalar width, SkScalar height,
SkCanvas* beginRecording(const SkRect& bounds,
SkBBHFactory* bbhFactory = NULL,
uint32_t recordFlags = 0);
SkCanvas* beginRecording(SkScalar width, SkScalar height,
SkBBHFactory* bbhFactory = NULL,
uint32_t recordFlags = 0) {
return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags);
}
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
@ -79,8 +85,7 @@ private:
void partialReplay(SkCanvas* canvas) const;
uint32_t fFlags;
SkScalar fCullWidth;
SkScalar fCullHeight;
SkRect fCullRect;
SkAutoTUnref<SkBBoxHierarchy> fBBH;
SkAutoTUnref<SkRecorder> fRecorder;
SkAutoTDelete<SkRecord> fRecord;

View File

@ -9,15 +9,20 @@
#include "SkRTree.h"
#include "SkTileGrid.h"
SkBBoxHierarchy* SkRTreeFactory::operator()(int width, int height) const {
SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(width), SkIntToScalar(height));
SkBBoxHierarchy* SkRTreeFactory::operator()(const SkRect& bounds) const {
SkScalar aspectRatio = bounds.width() / bounds.height();
return SkNEW_ARGS(SkRTree, (aspectRatio));
}
SkBBoxHierarchy* SkTileGridFactory::operator()(int width, int height) const {
SkBBoxHierarchy* SkTileGridFactory::operator()(const SkRect& bounds) const {
SkASSERT(fInfo.fMargin.width() >= 0);
SkASSERT(fInfo.fMargin.height() >= 0);
// We want a conservative answer for the size...
const SkIRect ibounds = bounds.roundOut();
const int width = ibounds.width();
const int height = ibounds.height();
// Note: SkIRects are non-inclusive of the right() column and bottom() row.
// For example, an SkIRect at 0,0 with a size of (1,1) will only have
// content at pixel (0,0) and will report left=0 and right=1, hence the

View File

@ -431,7 +431,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
}
device->onAttachToCanvas(this);
fMCRec->fLayer->fDevice = SkRef(device);
fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height()));
fMCRec->fRasterClip.setRect(device->getGlobalBounds());
}
return device;
}
@ -453,7 +453,11 @@ static SkBitmap make_nopixels(int width, int height) {
class SkNoPixelsBitmapDevice : public SkBitmapDevice {
public:
SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {}
SkNoPixelsBitmapDevice(const SkIRect& bounds)
: INHERITED(make_nopixels(bounds.width(), bounds.height()))
{
this->setOrigin(bounds.x(), bounds.y());
}
private:
@ -466,16 +470,17 @@ SkCanvas::SkCanvas(int width, int height)
{
inc_canvas();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice,
(SkIRect::MakeWH(width, height))), kDefault_InitFlags)->unref();
}
SkCanvas::SkCanvas(int width, int height, InitFlags flags)
SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (bounds)), flags)->unref();
}
SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags)

View File

@ -23,9 +23,22 @@ static int32_t next_generation_id() {
SkCanvasDrawable::SkCanvasDrawable() : fGenerationID(0) {}
static void draw_bbox(SkCanvas* canvas, const SkRect& r) {
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(0xFFFF7088);
canvas->drawRect(r, paint);
canvas->drawLine(r.left(), r.top(), r.right(), r.bottom(), paint);
canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint);
}
void SkCanvasDrawable::draw(SkCanvas* canvas) {
SkAutoCanvasRestore acr(canvas, true);
this->onDraw(canvas);
if (false) {
draw_bbox(canvas, this->getBounds());
}
}
SkPicture* SkCanvasDrawable::newPictureSnapshot(SkBBHFactory* bbhFactory, uint32_t recordFlags) {
@ -52,8 +65,13 @@ void SkCanvasDrawable::notifyDrawingChanged() {
#include "SkPictureRecorder.h"
SkPicture* SkCanvasDrawable::onNewPictureSnapshot(SkBBHFactory* bbhFactory, uint32_t recordFlags) {
const SkRect bounds = this->getBounds();
SkPictureRecorder recorder;
this->draw(recorder.beginRecording(bounds.width(), bounds.height(), bbhFactory, recordFlags));
const SkRect bounds = this->getBounds();
SkCanvas* canvas = recorder.beginRecording(bounds, bbhFactory, recordFlags);
this->draw(canvas);
if (false) {
draw_bbox(canvas, bounds);
}
return recorder.endRecording();
}

View File

@ -530,10 +530,9 @@ uint32_t SkPicture::uniqueID() const {
return fUniqueID;
}
SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkData* drawablePicts,
SkPicture::SkPicture(const SkRect& cullRect, SkRecord* record, SkData* drawablePicts,
SkBBoxHierarchy* bbh)
: fCullWidth(width)
, fCullHeight(height)
: fCullRect(cullRect)
, fRecord(record)
, fBBH(SkSafeRef(bbh))
, fDrawablePicts(SkSafeRef(drawablePicts))

View File

@ -18,20 +18,19 @@ SkPictureRecorder::SkPictureRecorder() {}
SkPictureRecorder::~SkPictureRecorder() {}
SkCanvas* SkPictureRecorder::beginRecording(SkScalar width, SkScalar height,
SkCanvas* SkPictureRecorder::beginRecording(const SkRect& cullRect,
SkBBHFactory* bbhFactory /* = NULL */,
uint32_t recordFlags /* = 0 */) {
fCullRect = cullRect;
fFlags = recordFlags;
fCullWidth = width;
fCullHeight = height;
if (bbhFactory) {
fBBH.reset((*bbhFactory)(width, height));
fBBH.reset((*bbhFactory)(cullRect));
SkASSERT(fBBH.get());
}
fRecord.reset(SkNEW(SkRecord));
fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), width, height)));
fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), cullRect)));
return this->getRecordingCanvas();
}
@ -52,12 +51,10 @@ SkPicture* SkPictureRecorder::endRecording() {
}
if (fBBH.get()) {
SkRect cullRect = SkRect::MakeWH(fCullWidth, fCullHeight);
if (saveLayerData) {
SkRecordComputeLayers(cullRect, *fRecord, fBBH.get(), saveLayerData);
SkRecordComputeLayers(fCullRect, *fRecord, fBBH.get(), saveLayerData);
} else {
SkRecordFillBounds(cullRect, *fRecord, fBBH.get());
SkRecordFillBounds(fCullRect, *fRecord, fBBH.get());
}
}
@ -65,7 +62,7 @@ SkPicture* SkPictureRecorder::endRecording() {
SkBBHFactory* factory = NULL;
uint32_t recordFlags = 0;
SkAutoDataUnref drawablePicts(fRecorder->newDrawableSnapshot(factory, recordFlags));
SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, fRecord.detach(),
SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord.detach(),
drawablePicts, fBBH.get()));
if (saveLayerData) {

View File

@ -10,9 +10,13 @@
#include "SkPatchUtils.h"
#include "SkPicture.h"
// SkCanvas will fail in mysterious ways if it doesn't know the real width and height.
SkRecorder::SkRecorder(SkRecord* record, int width, int height)
: SkCanvas(width, height, SkCanvas::kConservativeRasterClip_InitFlag)
: SkCanvas(SkIRect::MakeWH(width, height), SkCanvas::kConservativeRasterClip_InitFlag)
, fRecord(record)
, fSaveLayerCount(0) {}
SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds)
: SkCanvas(bounds.roundOut(), SkCanvas::kConservativeRasterClip_InitFlag)
, fRecord(record)
, fSaveLayerCount(0) {}

View File

@ -18,7 +18,8 @@
class SkRecorder : public SkCanvas {
public:
// Does not take ownership of the SkRecord.
SkRecorder(SkRecord*, int width, int height);
SkRecorder(SkRecord*, int width, int height); // legacy version
SkRecorder(SkRecord*, const SkRect& bounds);
virtual ~SkRecorder() SK_OVERRIDE;
// return a (new or ref'd) data containing the array of pictures that were

View File

@ -1842,7 +1842,7 @@ struct CountingBBH : public SkBBoxHierarchy {
class SpoonFedBBHFactory : public SkBBHFactory {
public:
explicit SpoonFedBBHFactory(SkBBoxHierarchy* bbh) : fBBH(bbh) {}
virtual SkBBoxHierarchy* operator()(int width, int height) const {
SkBBoxHierarchy* operator()(const SkRect&) const SK_OVERRIDE {
return SkRef(fBBH);
}
private: