used for interpreting the clipstack when a device is a layer



git-svn-id: http://skia.googlecode.com/svn/trunk@894 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-03-04 22:27:10 +00:00
Родитель f966fd35cf
Коммит 6f8f292aa7
10 изменённых файлов: 128 добавлений и 67 удалений

Просмотреть файл

@ -28,7 +28,11 @@ class GrClip {
public: public:
GrClip(); GrClip();
GrClip(const GrClip& src); GrClip(const GrClip& src);
GrClip(GrClipIterator* iter, const GrRect* bounds = NULL); /**
* If specified, the bounds parameter already takes (tx,ty) into account.
*/
GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds = NULL);
GrClip(const GrIRect& rect); GrClip(const GrIRect& rect);
GrClip(const GrRect& rect); GrClip(const GrRect& rect);
@ -77,7 +81,12 @@ public:
* Resets this clip to be empty * Resets this clip to be empty
*/ */
void setEmpty(); void setEmpty();
void setFromIterator(GrClipIterator* iter, const GrRect* bounds = NULL);
/**
* If specified, the bounds parameter already takes (tx,ty) into account.
*/
void setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds = NULL);
void setFromRect(const GrRect& rect); void setFromRect(const GrRect& rect);
void setFromIRect(const GrIRect& rect); void setFromIRect(const GrIRect& rect);

Просмотреть файл

@ -46,6 +46,12 @@ public:
GrScalar x2, GrScalar y2); GrScalar x2, GrScalar y2);
virtual void close(); virtual void close();
/**
* Offset the path by (tx, ty), adding tx to the horizontal position
* and adds ty to the vertical position of every point.
*/
void offset(GrScalar tx, GrScalar ty);
class Iter : public GrPathIter { class Iter : public GrPathIter {
public: public:
/** /**

Просмотреть файл

@ -223,6 +223,14 @@ struct GrRect {
fBottom >= r.fBottom; fBottom >= r.fBottom;
} }
/**
* Offset the rectangle by (tx, ty), adding tx to the horizontal position
* and adds ty to the vertical position.
*/
void offset(GrScalar tx, GrScalar ty) {
fLeft += tx; fTop += ty;
fRight += tx; fBottom += ty;
}
/** /**
* Initialize a rectangle to a point. * Initialize a rectangle to a point.

Просмотреть файл

@ -38,9 +38,10 @@ GrClip::GrClip(const GrRect& rect)
this->setFromRect(rect); this->setFromRect(rect);
} }
GrClip::GrClip(GrClipIterator* iter, const GrRect* bounds) GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds)
: fList(fListMemory, kPreAllocElements) { : fList(fListMemory, kPreAllocElements) {
this->setFromIterator(iter, bounds); this->setFromIterator(iter, tx, ty, bounds);
} }
GrClip::~GrClip() {} GrClip::~GrClip() {}
@ -86,7 +87,8 @@ void GrClip::setFromIRect(const GrIRect& r) {
} }
} }
void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) { void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds) {
fList.reset(); fList.reset();
int rectCount = 0; int rectCount = 0;
@ -104,6 +106,9 @@ void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) {
switch (e.fType) { switch (e.fType) {
case kRect_ClipType: case kRect_ClipType:
iter->getRect(&e.fRect); iter->getRect(&e.fRect);
if (tx || ty) {
e.fRect.offset(tx, ty);
}
++rectCount; ++rectCount;
if (isectRectValid) { if (isectRectValid) {
if (1 == rectCount || kIntersect_SetOp == e.fOp) { if (1 == rectCount || kIntersect_SetOp == e.fOp) {
@ -122,6 +127,9 @@ void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) {
break; break;
case kPath_ClipType: case kPath_ClipType:
e.fPath.resetFromIter(iter->getPathIter()); e.fPath.resetFromIter(iter->getPathIter());
if (tx || ty) {
e.fPath.offset(tx, ty);
}
e.fPathFill = iter->getPathFill(); e.fPathFill = iter->getPathFill();
isectRectValid = false; isectRectValid = false;
break; break;

Просмотреть файл

@ -84,6 +84,21 @@ void GrPath::close() {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void GrPath::offset(GrScalar tx, GrScalar ty) {
if (!tx && !ty) {
return; // nothing to do
}
GrPoint* iter = fPts.begin();
GrPoint* stop = fPts.end();
while (iter < stop) {
iter->offset(tx, ty);
++iter;
}
}
///////////////////////////////////////////////////////////////////////////////
static bool check_two_vecs(const GrVec& prevVec, static bool check_two_vecs(const GrVec& prevVec,
const GrVec& currVec, const GrVec& currVec,
GrScalar turnDir, GrScalar turnDir,

Просмотреть файл

@ -81,6 +81,13 @@ public:
/** Return the height of the device (in pixels). /** Return the height of the device (in pixels).
*/ */
virtual int height() const { return fBitmap.height(); } virtual int height() const { return fBitmap.height(); }
/**
* Return the device's origin: its offset in device coordinates from
* the default origin in its canvas' matrix/clip
*/
const SkIPoint& getOrigin() const { return fOrigin; }
/** Return the bitmap config of the device's pixels /** Return the bitmap config of the device's pixels
*/ */
SkBitmap::Config config() const { return fBitmap.getConfig(); } SkBitmap::Config config() const { return fBitmap.getConfig(); }
@ -217,9 +224,14 @@ protected:
} }
private: private:
friend class SkCanvas;
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
SkCanvas* fCanvas; SkCanvas* fCanvas;
SkBitmap fBitmap; SkBitmap fBitmap;
SkRefDict fRefDict; SkRefDict fRefDict;
SkIPoint fOrigin;
}; };
#endif #endif

Просмотреть файл

@ -33,6 +33,21 @@ struct SkIPoint {
return pt; return pt;
} }
int32_t x() const { return fX; }
int32_t y() const { return fY; }
void setX(int32_t x) { fX = x; }
void setY(int32_t y) { fY = y; }
/**
* Returns true iff fX and fY are both zero.
*/
bool isZero() const { return (fX | fY) == 0; }
/**
* Set both fX and fY to zero. Same as set(0, 0)
*/
void setZero() { fX = fY = 0; }
/** Set the x and y values of the point. */ /** Set the x and y values of the point. */
void set(int32_t x, int32_t y) { fX = x; fY = y; } void set(int32_t x, int32_t y) { fX = x; fY = y; }

Просмотреть файл

@ -72,8 +72,7 @@ struct DeviceCM {
SkDevice* fDevice; SkDevice* fDevice;
SkRegion fClip; SkRegion fClip;
const SkMatrix* fMatrix; const SkMatrix* fMatrix;
SkPaint* fPaint; // may be null (in the future) SkPaint* fPaint; // may be null (in the future)
int16_t fX, fY; // relative to base matrix/clip
// optional, related to canvas' external matrix // optional, related to canvas' external matrix
const SkMatrix* fMVMatrix; const SkMatrix* fMVMatrix;
const SkMatrix* fExtMatrix; const SkMatrix* fExtMatrix;
@ -85,8 +84,6 @@ struct DeviceCM {
device->lockPixels(); device->lockPixels();
} }
fDevice = device; fDevice = device;
fX = SkToS16(x);
fY = SkToS16(y);
fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
} }
@ -100,8 +97,8 @@ struct DeviceCM {
void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip, void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip,
const SkClipStack& clipStack, SkRegion* updateClip) { const SkClipStack& clipStack, SkRegion* updateClip) {
int x = fX; int x = fDevice->getOrigin().x();
int y = fY; int y = fDevice->getOrigin().y();
int width = fDevice->width(); int width = fDevice->width();
int height = fDevice->height(); int height = fDevice->height();
@ -147,12 +144,6 @@ struct DeviceCM {
fExtMatrix = &extM; // assumes extM has long life-time (owned by canvas) fExtMatrix = &extM; // assumes extM has long life-time (owned by canvas)
} }
void translateClip() {
if (fX | fY) {
fClip.translate(fX, fY);
}
}
private: private:
SkMatrix fMatrixStorage, fMVMatrixStorage; SkMatrix fMatrixStorage, fMVMatrixStorage;
}; };
@ -251,8 +242,6 @@ public:
fClip = &rec->fClip; fClip = &rec->fClip;
fDevice = rec->fDevice; fDevice = rec->fDevice;
fBitmap = &fDevice->accessBitmap(true); fBitmap = &fDevice->accessBitmap(true);
fLayerX = rec->fX;
fLayerY = rec->fY;
fPaint = rec->fPaint; fPaint = rec->fPaint;
fMVMatrix = rec->fMVMatrix; fMVMatrix = rec->fMVMatrix;
fExtMatrix = rec->fExtMatrix; fExtMatrix = rec->fExtMatrix;
@ -270,18 +259,17 @@ public:
return false; return false;
} }
int getX() const { return fLayerX; }
int getY() const { return fLayerY; }
SkDevice* getDevice() const { return fDevice; } SkDevice* getDevice() const { return fDevice; }
int getX() const { return fDevice->getOrigin().x(); }
int getY() const { return fDevice->getOrigin().y(); }
const SkMatrix& getMatrix() const { return *fMatrix; } const SkMatrix& getMatrix() const { return *fMatrix; }
const SkRegion& getClip() const { return *fClip; } const SkRegion& getClip() const { return *fClip; }
const SkPaint* getPaint() const { return fPaint; } const SkPaint* getPaint() const { return fPaint; }
private: private:
SkCanvas* fCanvas; SkCanvas* fCanvas;
const DeviceCM* fCurrLayer; const DeviceCM* fCurrLayer;
const SkPaint* fPaint; // May be null. const SkPaint* fPaint; // May be null.
int fLayerX;
int fLayerY;
SkBool8 fSkipEmptyClips; SkBool8 fSkipEmptyClips;
typedef SkDraw INHERITED; typedef SkDraw INHERITED;
@ -748,6 +736,7 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
SkDevice* device = this->createDevice(config, ir.width(), ir.height(), SkDevice* device = this->createDevice(config, ir.width(), ir.height(),
isOpaque, true); isOpaque, true);
device->setOrigin(ir.fLeft, ir.fTop);
DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint)); DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint));
device->unref(); device->unref();
@ -800,7 +789,8 @@ void SkCanvas::internalRestore() {
*/ */
if (NULL != layer) { if (NULL != layer) {
if (layer->fNext) { if (layer->fNext) {
this->drawDevice(layer->fDevice, layer->fX, layer->fY, const SkIPoint& origin = layer->fDevice->getOrigin();
this->drawDevice(layer->fDevice, origin.x(), origin.y(),
layer->fPaint); layer->fPaint);
// reset this, since drawDevice will have set it to true // reset this, since drawDevice will have set it to true
fDeviceCMDirty = true; fDeviceCMDirty = true;
@ -1035,9 +1025,9 @@ void SkCanvas::validateClip() const {
} }
} }
#if 0 // enable this locally for testing
// now compare against the current rgn // now compare against the current rgn
const SkRegion& rgn = this->getTotalClip(); const SkRegion& rgn = this->getTotalClip();
#if 0 // disable for now (reed)
SkASSERT(rgn == clipRgn); SkASSERT(rgn == clipRgn);
#endif #endif
} }

Просмотреть файл

@ -4,10 +4,13 @@
SkDeviceFactory::~SkDeviceFactory() {} SkDeviceFactory::~SkDeviceFactory() {}
SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {} SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {
fOrigin.setZero();
}
SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer) SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
: fCanvas(canvas), fBitmap(bitmap) { : fCanvas(canvas), fBitmap(bitmap) {
fOrigin.setZero();
// auto-allocate if we're for offscreen drawing // auto-allocate if we're for offscreen drawing
if (isForLayer) { if (isForLayer) {
if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) { if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) {

Просмотреть файл

@ -267,29 +267,24 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define USE_CLIP_STACK 0
static void convert_matrixclip(GrContext* context, const SkMatrix& matrix, static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
const SkClipStack& clipStack, const SkClipStack& clipStack,
const SkRegion& clipRegion) { const SkRegion& clipRegion,
const SkIPoint& origin) {
GrMatrix grmat; GrMatrix grmat;
SkGr::SkMatrix2GrMatrix(matrix, &grmat); SkGr::SkMatrix2GrMatrix(matrix, &grmat);
context->setMatrix(grmat); context->setMatrix(grmat);
#if USE_CLIP_STACK
SkGrClipIterator iter; SkGrClipIterator iter;
iter.reset(clipStack); iter.reset(clipStack);
#else
SkGrRegionIterator iter;
iter.reset(clipRegion);
#endif
const SkIRect& skBounds = clipRegion.getBounds(); const SkIRect& skBounds = clipRegion.getBounds();
GrRect bounds; GrRect bounds;
bounds.setLTRB(GrIntToScalar(skBounds.fLeft), bounds.setLTRB(GrIntToScalar(skBounds.fLeft),
GrIntToScalar(skBounds.fTop), GrIntToScalar(skBounds.fTop),
GrIntToScalar(skBounds.fRight), GrIntToScalar(skBounds.fRight),
GrIntToScalar(skBounds.fBottom)); GrIntToScalar(skBounds.fBottom));
GrClip grc(&iter, &bounds); GrClip grc(&iter, GrIntToScalar(-origin.x()), GrIntToScalar(-origin.y()),
&bounds);
context->setClip(grc); context->setClip(grc);
} }
@ -302,7 +297,7 @@ void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
fContext->setRenderTarget(fRenderTarget); fContext->setRenderTarget(fRenderTarget);
SkASSERT(draw.fClipStack); SkASSERT(draw.fClipStack);
convert_matrixclip(fContext, *draw.fMatrix, convert_matrixclip(fContext, *draw.fMatrix,
*draw.fClipStack, *draw.fClip); *draw.fClipStack, *draw.fClip, this->getOrigin());
fNeedPrepareRenderTarget = false; fNeedPrepareRenderTarget = false;
} }
} }
@ -311,7 +306,7 @@ void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
const SkClipStack& clipStack) { const SkClipStack& clipStack) {
this->INHERITED::setMatrixClip(matrix, clip, clipStack); this->INHERITED::setMatrixClip(matrix, clip, clipStack);
convert_matrixclip(fContext, matrix, clipStack, clip); convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
} }
void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix, void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
@ -321,7 +316,7 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
this->INHERITED::gainFocus(canvas, matrix, clip, clipStack); this->INHERITED::gainFocus(canvas, matrix, clip, clipStack);
convert_matrixclip(fContext, matrix, clipStack, clip); convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
if (fNeedClear) { if (fNeedClear) {
fContext->eraseColor(0x0); fContext->eraseColor(0x0);