aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-11 19:32:32 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-11 19:32:32 +0000
commit5dc26b97366934ba0f896cea02a3fec027d5d5c1 (patch)
treef9be03e4ed22947191a696269d4d735d0a06a52e /src
parentb364eb6c871c88710534c444cc4f075fcb9e3c02 (diff)
SkTCopyOnFirstWrite
R=reed@google.com Review URL: https://codereview.appspot.com/6650047 git-svn-id: http://skia.googlecode.com/svn/trunk@5905 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBlitter.cpp31
-rw-r--r--src/core/SkDraw.cpp14
-rw-r--r--src/device/xps/SkXPSDevice.cpp59
-rw-r--r--src/gpu/GrContext.cpp22
-rw-r--r--src/gpu/SkGpuDevice.cpp1
5 files changed, 44 insertions, 83 deletions
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 322f91d40d..cdb2b625a7 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -847,17 +847,13 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
SkXfermode* mode = origPaint.getXfermode();
Sk3DShader* shader3D = NULL;
- SkTLazy<SkPaint> lazyPaint;
- // we promise not to mutate paint unless we know we've reassigned it from
- // lazyPaint
- SkPaint* paint = const_cast<SkPaint*>(&origPaint);
+ SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
if (origPaint.getMaskFilter() != NULL &&
origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
shader3D = SkNEW_ARGS(Sk3DShader, (shader));
// we know we haven't initialized lazyPaint yet, so just do it
- paint = lazyPaint.set(origPaint);
- paint->setShader(shader3D)->unref();
+ paint.writable()->setShader(shader3D)->unref();
shader = shader3D;
}
@@ -865,10 +861,7 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
switch (interpret_xfermode(*paint, mode, device.config())) {
case kSrcOver_XferInterp:
mode = NULL;
- if (!lazyPaint.isValid()) {
- paint = lazyPaint.set(origPaint);
- }
- paint->setXfermode(NULL);
+ paint.writable()->setXfermode(NULL);
break;
case kSkipDrawing_XferInterp:
SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
@@ -886,18 +879,13 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
#endif
// xfermodes (and filters) require shaders for our current blitters
shader = SkNEW(SkColorShader);
- if (!lazyPaint.isValid()) {
- paint = lazyPaint.set(origPaint);
- }
- paint->setShader(shader)->unref();
+ paint.writable()->setShader(shader)->unref();
} else if (cf) {
// if no shader && no xfermode, we just apply the colorfilter to
// our color and move on.
- if (!lazyPaint.isValid()) {
- paint = lazyPaint.set(origPaint);
- }
- paint->setColor(cf->filterColor(paint->getColor()));
- paint->setColorFilter(NULL);
+ SkPaint* writablePaint = paint.writable();
+ writablePaint->setColor(cf->filterColor(paint->getColor()));
+ writablePaint->setColorFilter(NULL);
cf = NULL;
}
}
@@ -905,10 +893,7 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
if (cf) {
SkASSERT(shader);
shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
- if (!lazyPaint.isValid()) {
- paint = lazyPaint.set(origPaint);
- }
- paint->setShader(shader)->unref();
+ paint.writable()->setShader(shader)->unref();
// blitters should ignore the presence/absence of a filter, since
// if there is one, the shader will take care of it.
}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index cdd59c1cdb..885a810836 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -931,16 +931,13 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
// at this point we're done with prePathMatrix
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
- const SkPaint* paint = &origPaint;
- SkTLazy<SkPaint> lazyPaint;
+ SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
{
SkScalar coverage;
if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
if (SK_Scalar1 == coverage) {
- lazyPaint.set(origPaint);
- lazyPaint.get()->setStrokeWidth(0);
- paint = lazyPaint.get();
+ paint.writable()->setStrokeWidth(0);
} else if (xfermodeSupportsCoverageAsAlpha(origPaint.getXfermode())) {
U8CPU newAlpha;
#if 0
@@ -953,10 +950,9 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
int scale = (int)SkScalarMul(coverage, 256);
newAlpha = origPaint.getAlpha() * scale >> 8;
#endif
- lazyPaint.set(origPaint);
- lazyPaint.get()->setStrokeWidth(0);
- lazyPaint.get()->setAlpha(newAlpha);
- paint = lazyPaint.get();
+ SkPaint* writablePaint = paint.writable();
+ writablePaint->setStrokeWidth(0);
+ writablePaint->setAlpha(newAlpha);
}
}
}
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index 9c5958394c..8e62d49205 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -1143,15 +1143,14 @@ void SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
SkDEBUGF(("XPS drawVertices not yet implemented."));
}
-void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
+void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);
//If trying to paint with a stroke, ignore that and fill.
- SkPaint* fillPaint = const_cast<SkPaint*>(&paint);
- SkTLazy<SkPaint> modifiedPaint;
- if (paint.getStyle() != SkPaint::kFill_Style) {
- fillPaint = modifiedPaint.set(paint);
- fillPaint->setStyle(SkPaint::kFill_Style);
+ SkPaint* fillPaint = const_cast<SkPaint*>(&origPaint);
+ SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
+ if (paint->getStyle() != SkPaint::kFill_Style) {
+ paint.writable()->setStyle(SkPaint::kFill_Style);
}
this->internalDrawRect(d, r, false, *fillPaint);
@@ -1640,24 +1639,26 @@ HRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath,
void SkXPSDevice::drawPath(const SkDraw& d,
const SkPath& platonicPath,
- const SkPaint& paint,
+ const SkPaint& origPaint,
const SkMatrix* prePathMatrix,
bool pathIsMutable) {
+ SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
+
// nothing to draw
if (d.fClip->isEmpty() ||
- (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
+ (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
return;
}
SkPath modifiedPath;
- const bool paintHasPathEffect = paint.getPathEffect()
- || paint.getStyle() != SkPaint::kFill_Style;
+ const bool paintHasPathEffect = paint->getPathEffect()
+ || paint->getStyle() != SkPaint::kFill_Style;
//Apply pre-path matrix [Platonic-path -> Skeletal-path].
SkMatrix matrix = *d.fMatrix;
SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);
if (prePathMatrix) {
- if (paintHasPathEffect || paint.getRasterizer()) {
+ if (paintHasPathEffect || paint->getRasterizer()) {
if (!pathIsMutable) {
skeletalPath = &modifiedPath;
pathIsMutable = true;
@@ -1670,9 +1671,6 @@ void SkXPSDevice::drawPath(const SkDraw& d,
}
}
- SkTLazy<SkPaint> lazyShaderPaint;
- SkPaint* shaderPaint = const_cast<SkPaint*>(&paint);
-
//Apply path effect [Skeletal-path -> Fillable-path].
SkPath* fillablePath = skeletalPath;
if (paintHasPathEffect) {
@@ -1680,15 +1678,15 @@ void SkXPSDevice::drawPath(const SkDraw& d,
fillablePath = &modifiedPath;
pathIsMutable = true;
}
- bool fill = paint.getFillPath(*skeletalPath, fillablePath);
+ bool fill = paint->getFillPath(*skeletalPath, fillablePath);
- shaderPaint = lazyShaderPaint.set(*shaderPaint);
- shaderPaint->setPathEffect(NULL);
+ SkPaint* writablePaint = paint.writable();
+ writablePaint->setPathEffect(NULL);
if (fill) {
- shaderPaint->setStyle(SkPaint::kFill_Style);
+ writablePaint->setStyle(SkPaint::kFill_Style);
} else {
- shaderPaint->setStyle(SkPaint::kStroke_Style);
- shaderPaint->setStrokeWidth(0);
+ writablePaint->setStyle(SkPaint::kStroke_Style);
+ writablePaint->setStrokeWidth(0);
}
}
@@ -1706,22 +1704,13 @@ void SkXPSDevice::drawPath(const SkDraw& d,
HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()),
"Could not add the shaded geometry to shaded path.");
- SkRasterizer* rasterizer = paint.getRasterizer();
- SkMaskFilter* filter = paint.getMaskFilter();
-
- SkTLazy<SkPaint> lazyRasterizePaint;
- const SkPaint* rasterizePaint = shaderPaint;
+ SkRasterizer* rasterizer = paint->getRasterizer();
+ SkMaskFilter* filter = paint->getMaskFilter();
//Determine if we will draw or shade and mask.
if (rasterizer || filter) {
- if (shaderPaint->getStyle() != SkPaint::kFill_Style) {
- if (lazyShaderPaint.isValid()) {
- rasterizePaint = lazyRasterizePaint.set(*shaderPaint);
- } else {
- rasterizePaint = shaderPaint;
- shaderPaint = lazyShaderPaint.set(*shaderPaint);
- }
- shaderPaint->setStyle(SkPaint::kFill_Style);
+ if (paint->getStyle() != SkPaint::kFill_Style) {
+ paint.writable()->setStyle(SkPaint::kFill_Style);
}
}
@@ -1729,7 +1718,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
BOOL fill;
BOOL stroke;
HRV(this->shadePath(shadedPath.get(),
- *shaderPaint,
+ *paint,
*d.fMatrix,
&fill,
&stroke));
@@ -1801,7 +1790,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
&matrix,
&rasteredMask,
SkMask::kComputeBoundsAndRenderImage_CreateMode,
- rasterizePaint->getStyle())) {
+ paint->getStyle())) {
SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage);
mask = &rasteredMask;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 738521b094..8997280ac8 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -582,7 +582,7 @@ void GrContext::clear(const GrIRect* rect,
this->prepareToDraw(NULL, DEFAULT_BUFFERING)->clear(rect, color, target);
}
-void GrContext::drawPaint(const GrPaint& paint) {
+void GrContext::drawPaint(const GrPaint& origPaint) {
// set rect to be big enough to fill the space, but not super-huge, so we
// don't overflow fixed-point implementations
GrRect r;
@@ -590,8 +590,7 @@ void GrContext::drawPaint(const GrPaint& paint) {
GrIntToScalar(getRenderTarget()->width()),
GrIntToScalar(getRenderTarget()->height()));
GrMatrix inverse;
- SkTLazy<GrPaint> tmpPaint;
- const GrPaint* p = &paint;
+ SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
AutoMatrix am;
// We attempt to map r by the inverse matrix and draw that. mapRect will
@@ -604,25 +603,18 @@ void GrContext::drawPaint(const GrPaint& paint) {
}
inverse.mapRect(&r);
} else {
- if (paint.hasStage()) {
- tmpPaint.set(paint);
- p = tmpPaint.get();
- if (!tmpPaint.get()->preConcatSamplerMatricesWithInverse(fDrawState->getViewMatrix())) {
+ if (paint->hasStage()) {
+ if (!paint.writable()->preConcatSamplerMatricesWithInverse(fDrawState->getViewMatrix())) {
GrPrintf("Could not invert matrix\n");
}
}
am.set(this, GrMatrix::I());
}
// by definition this fills the entire clip, no need for AA
- if (paint.isAntiAlias()) {
- if (!tmpPaint.isValid()) {
- tmpPaint.set(paint);
- p = tmpPaint.get();
- }
- GrAssert(p == tmpPaint.get());
- tmpPaint.get()->setAntiAlias(false);
+ if (paint->isAntiAlias()) {
+ paint.writable()->setAntiAlias(false);
}
- this->drawRect(*p, r);
+ this->drawRect(*paint, r);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b168e57e63..df7754db24 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -20,7 +20,6 @@
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
#include "SkImageFilter.h"
-#include "SkTLazy.h"
#include "SkUtils.h"
#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1