don/t modify const paint, since it could be used in different threads
git-svn-id: http://skia.googlecode.com/svn/trunk@1953 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
aab1fd921c
commit
40c2ba27b6
@ -67,17 +67,12 @@ private:
|
|||||||
SkBounder* fBounder;
|
SkBounder* fBounder;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SkPoint* rect_points(SkRect& r, int index) {
|
|
||||||
SkASSERT((unsigned)index < 2);
|
|
||||||
return &((SkPoint*)(void*)&r)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper for allocating small blitters on the stack.
|
/** Helper for allocating small blitters on the stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2)
|
#define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2)
|
||||||
|
|
||||||
class SkAutoBlitterChoose {
|
class SkAutoBlitterChoose : SkNoncopyable {
|
||||||
public:
|
public:
|
||||||
SkAutoBlitterChoose() {
|
SkAutoBlitterChoose() {
|
||||||
fBlitter = NULL;
|
fBlitter = NULL;
|
||||||
@ -113,23 +108,30 @@ SkAutoBlitterChoose::~SkAutoBlitterChoose() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SkAutoBitmapShaderInstall {
|
/**
|
||||||
|
* Since we are providing the storage for the shader (to avoid the perf cost
|
||||||
|
* of calling new) we insist that in our destructor we can account for all
|
||||||
|
* owners of the shader.
|
||||||
|
*/
|
||||||
|
class SkAutoBitmapShaderInstall : SkNoncopyable {
|
||||||
public:
|
public:
|
||||||
SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint* paint)
|
SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint)
|
||||||
: fPaint((SkPaint*)paint) {
|
: fPaint(paint) /* makes a copy of the paint */ {
|
||||||
fPrevShader = paint->getShader();
|
fPaint.setShader(SkShader::CreateBitmapShader(src,
|
||||||
SkSafeRef(fPrevShader);
|
|
||||||
fPaint->setShader(SkShader::CreateBitmapShader( src,
|
|
||||||
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
|
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
|
||||||
fStorage, sizeof(fStorage)));
|
fStorage, sizeof(fStorage)));
|
||||||
|
// we deliberately left the shader with an owner-count of 2
|
||||||
|
SkASSERT(2 == fPaint.getShader()->getRefCnt());
|
||||||
}
|
}
|
||||||
|
|
||||||
~SkAutoBitmapShaderInstall() {
|
~SkAutoBitmapShaderInstall() {
|
||||||
SkShader* shader = fPaint->getShader();
|
SkShader* shader = fPaint.getShader();
|
||||||
|
// since we manually destroy shader, we insist that owners == 2
|
||||||
|
SkASSERT(2 == shader->getRefCnt());
|
||||||
|
|
||||||
fPaint->setShader(fPrevShader);
|
fPaint.setShader(NULL); // unref the shader by 1
|
||||||
SkSafeUnref(fPrevShader);
|
|
||||||
|
|
||||||
|
// now destroy to take care of the 2nd owner-count
|
||||||
if ((void*)shader == (void*)fStorage) {
|
if ((void*)shader == (void*)fStorage) {
|
||||||
shader->~SkShader();
|
shader->~SkShader();
|
||||||
} else {
|
} else {
|
||||||
@ -137,33 +139,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return the new paint that has the shader applied
|
||||||
|
const SkPaint& paintWithShader() const { return fPaint; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkPaint* fPaint;
|
SkPaint fPaint; // copy of caller's paint (which we then modify)
|
||||||
SkShader* fPrevShader;
|
|
||||||
uint32_t fStorage[kBlitterStorageLongCount];
|
uint32_t fStorage[kBlitterStorageLongCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkAutoPaintStyleRestore {
|
|
||||||
public:
|
|
||||||
SkAutoPaintStyleRestore(const SkPaint& paint, SkPaint::Style style)
|
|
||||||
: fPaint((SkPaint&)paint) {
|
|
||||||
fStyle = paint.getStyle(); // record the old
|
|
||||||
fPaint.setStyle(style); // change it to the specified style
|
|
||||||
}
|
|
||||||
|
|
||||||
~SkAutoPaintStyleRestore() {
|
|
||||||
fPaint.setStyle(fStyle); // restore the old
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SkPaint& fPaint;
|
|
||||||
SkPaint::Style fStyle;
|
|
||||||
|
|
||||||
// illegal
|
|
||||||
SkAutoPaintStyleRestore(const SkAutoPaintStyleRestore&);
|
|
||||||
SkAutoPaintStyleRestore& operator=(const SkAutoPaintStyleRestore&);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkDraw::SkDraw() {
|
SkDraw::SkDraw() {
|
||||||
@ -628,12 +611,13 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SkCanvas::kPoints_PointMode: {
|
case SkCanvas::kPoints_PointMode: {
|
||||||
// temporarily mark the paint as filling.
|
// temporarily mark the paint as filling.
|
||||||
SkAutoPaintStyleRestore restore(paint, SkPaint::kFill_Style);
|
SkPaint newPaint(paint);
|
||||||
|
newPaint.setStyle(SkPaint::kFill_Style);
|
||||||
|
|
||||||
SkScalar width = paint.getStrokeWidth();
|
SkScalar width = newPaint.getStrokeWidth();
|
||||||
SkScalar radius = SkScalarHalf(width);
|
SkScalar radius = SkScalarHalf(width);
|
||||||
|
|
||||||
if (paint.getStrokeCap() == SkPaint::kRound_Cap) {
|
if (newPaint.getStrokeCap() == SkPaint::kRound_Cap) {
|
||||||
SkPath path;
|
SkPath path;
|
||||||
SkMatrix preMatrix;
|
SkMatrix preMatrix;
|
||||||
|
|
||||||
@ -643,10 +627,11 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
|||||||
// pass true for the last point, since we can modify
|
// pass true for the last point, since we can modify
|
||||||
// then path then
|
// then path then
|
||||||
if (fDevice) {
|
if (fDevice) {
|
||||||
fDevice->drawPath(*this, path, paint, &preMatrix,
|
fDevice->drawPath(*this, path, newPaint, &preMatrix,
|
||||||
(count-1) == i);
|
(count-1) == i);
|
||||||
} else {
|
} else {
|
||||||
this->drawPath(path, paint, &preMatrix, (count-1) == i);
|
this->drawPath(path, newPaint, &preMatrix,
|
||||||
|
(count-1) == i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -658,9 +643,9 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
|||||||
r.fRight = r.fLeft + width;
|
r.fRight = r.fLeft + width;
|
||||||
r.fBottom = r.fTop + width;
|
r.fBottom = r.fTop + width;
|
||||||
if (fDevice) {
|
if (fDevice) {
|
||||||
fDevice->drawRect(*this, r, paint);
|
fDevice->drawRect(*this, r, newPaint);
|
||||||
} else {
|
} else {
|
||||||
this->drawRect(r, paint);
|
this->drawRect(r, newPaint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,6 +725,11 @@ SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
|
|||||||
return rtype;
|
return rtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SkPoint* rect_points(SkRect& r, int index) {
|
||||||
|
SkASSERT((unsigned)index < 2);
|
||||||
|
return &((SkPoint*)(void*)&r)[index];
|
||||||
|
}
|
||||||
|
|
||||||
void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
|
void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
|
||||||
SkDEBUGCODE(this->validate();)
|
SkDEBUGCODE(this->validate();)
|
||||||
|
|
||||||
@ -1097,11 +1087,11 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
|
|||||||
// we manually build a shader and draw that into our new mask
|
// we manually build a shader and draw that into our new mask
|
||||||
SkPaint tmpPaint;
|
SkPaint tmpPaint;
|
||||||
tmpPaint.setFlags(paint.getFlags());
|
tmpPaint.setFlags(paint.getFlags());
|
||||||
SkAutoBitmapShaderInstall install(bitmap, &tmpPaint);
|
SkAutoBitmapShaderInstall install(bitmap, tmpPaint);
|
||||||
SkRect rr;
|
SkRect rr;
|
||||||
rr.set(0, 0, SkIntToScalar(bitmap.width()),
|
rr.set(0, 0, SkIntToScalar(bitmap.width()),
|
||||||
SkIntToScalar(bitmap.height()));
|
SkIntToScalar(bitmap.height()));
|
||||||
c.drawRect(rr, tmpPaint);
|
c.drawRect(rr, install.paintWithShader());
|
||||||
}
|
}
|
||||||
this->drawDevMask(mask, paint);
|
this->drawDevMask(mask, paint);
|
||||||
}
|
}
|
||||||
@ -1125,14 +1115,14 @@ static bool clipped_out(const SkMatrix& matrix, const SkRegion& clip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
|
void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
|
||||||
const SkPaint& paint) const {
|
const SkPaint& origPaint) const {
|
||||||
SkDEBUGCODE(this->validate();)
|
SkDEBUGCODE(this->validate();)
|
||||||
|
|
||||||
// nothing to draw
|
// nothing to draw
|
||||||
if (fClip->isEmpty() ||
|
if (fClip->isEmpty() ||
|
||||||
bitmap.width() == 0 || bitmap.height() == 0 ||
|
bitmap.width() == 0 || bitmap.height() == 0 ||
|
||||||
bitmap.getConfig() == SkBitmap::kNo_Config ||
|
bitmap.getConfig() == SkBitmap::kNo_Config ||
|
||||||
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
|
(origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,7 +1133,8 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SkAutoPaintStyleRestore restore(paint, SkPaint::kFill_Style);
|
SkPaint paint(origPaint);
|
||||||
|
paint.setStyle(SkPaint::kFill_Style);
|
||||||
|
|
||||||
SkMatrix matrix;
|
SkMatrix matrix;
|
||||||
if (!matrix.setConcat(*fMatrix, prematrix)) {
|
if (!matrix.setConcat(*fMatrix, prematrix)) {
|
||||||
@ -1208,25 +1199,25 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
|
|||||||
if (bitmap.getConfig() == SkBitmap::kA8_Config) {
|
if (bitmap.getConfig() == SkBitmap::kA8_Config) {
|
||||||
draw.drawBitmapAsMask(bitmap, paint);
|
draw.drawBitmapAsMask(bitmap, paint);
|
||||||
} else {
|
} else {
|
||||||
SkAutoBitmapShaderInstall install(bitmap, &paint);
|
SkAutoBitmapShaderInstall install(bitmap, paint);
|
||||||
|
|
||||||
SkRect r;
|
SkRect r;
|
||||||
r.set(0, 0, SkIntToScalar(bitmap.width()),
|
r.set(0, 0, SkIntToScalar(bitmap.width()),
|
||||||
SkIntToScalar(bitmap.height()));
|
SkIntToScalar(bitmap.height()));
|
||||||
// is this ok if paint has a rasterizer?
|
// is this ok if paint has a rasterizer?
|
||||||
draw.drawRect(r, paint);
|
draw.drawRect(r, install.paintWithShader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
|
void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||||
const SkPaint& paint) const {
|
const SkPaint& origPaint) const {
|
||||||
SkDEBUGCODE(this->validate();)
|
SkDEBUGCODE(this->validate();)
|
||||||
|
|
||||||
// nothing to draw
|
// nothing to draw
|
||||||
if (fClip->isEmpty() ||
|
if (fClip->isEmpty() ||
|
||||||
bitmap.width() == 0 || bitmap.height() == 0 ||
|
bitmap.width() == 0 || bitmap.height() == 0 ||
|
||||||
bitmap.getConfig() == SkBitmap::kNo_Config ||
|
bitmap.getConfig() == SkBitmap::kNo_Config ||
|
||||||
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
|
(origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,7 +1228,8 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
|
|||||||
return; // nothing to draw
|
return; // nothing to draw
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoPaintStyleRestore restore(paint, SkPaint::kFill_Style);
|
SkPaint paint(origPaint);
|
||||||
|
paint.setStyle(SkPaint::kFill_Style);
|
||||||
|
|
||||||
if (NULL == paint.getColorFilter()) {
|
if (NULL == paint.getColorFilter()) {
|
||||||
uint32_t storage[kBlitterStorageLongCount];
|
uint32_t storage[kBlitterStorageLongCount];
|
||||||
@ -1262,7 +1254,8 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoBitmapShaderInstall install(bitmap, &paint);
|
SkAutoBitmapShaderInstall install(bitmap, paint);
|
||||||
|
const SkPaint& shaderPaint = install.paintWithShader();
|
||||||
|
|
||||||
SkMatrix matrix;
|
SkMatrix matrix;
|
||||||
SkRect r;
|
SkRect r;
|
||||||
@ -1272,14 +1265,14 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
|
|||||||
|
|
||||||
// tell the shader our offset
|
// tell the shader our offset
|
||||||
matrix.setTranslate(r.fLeft, r.fTop);
|
matrix.setTranslate(r.fLeft, r.fTop);
|
||||||
paint.getShader()->setLocalMatrix(matrix);
|
shaderPaint.getShader()->setLocalMatrix(matrix);
|
||||||
|
|
||||||
SkDraw draw(*this);
|
SkDraw draw(*this);
|
||||||
matrix.reset();
|
matrix.reset();
|
||||||
draw.fMatrix = &matrix;
|
draw.fMatrix = &matrix;
|
||||||
// call ourself with a rect
|
// call ourself with a rect
|
||||||
// is this OK if paint has a rasterizer?
|
// is this OK if paint has a rasterizer?
|
||||||
draw.drawRect(r, paint);
|
draw.drawRect(r, shaderPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user