aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-17 13:10:25 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-06-17 13:10:25 +0000
commite97f0856a8044866b12527819d14cdfbcdfd96f2 (patch)
treed0273fcd80930ebfbb0e2640dd6d0adf3bbbf632 /src
parenta54e2f61f8d181b95dd1757d405eacf9f6a9d792 (diff)
Add createNewCompatibleDevice. Allow devices to have a NULL factory and saveLayer will fall back on createNewCompatibleDevice.
Review URL: http://codereview.appspot.com/4633044/ git-svn-id: http://skia.googlecode.com/svn/trunk@1625 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/core/SkCanvas.cpp44
-rw-r--r--src/core/SkDevice.cpp23
-rw-r--r--src/gpu/SkGpuDevice.cpp28
-rw-r--r--src/pdf/SkPDFDevice.cpp11
-rw-r--r--src/utils/SkProxyCanvas.cpp5
5 files changed, 85 insertions, 26 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 5b2e96459e..0b6f086313 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -434,10 +434,9 @@ SkCanvas::SkCanvas(SkDevice* device)
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
inc_canvas();
- fDeviceFactory = device->getDeviceFactory();
- SkASSERT(fDeviceFactory);
- fDeviceFactory->ref();
-
+ fDeviceFactory = device->getDeviceFactory();
+ SkSafeRef(fDeviceFactory);
+
this->init(device);
}
@@ -446,9 +445,8 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap)
inc_canvas();
SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
- fDeviceFactory = device->getDeviceFactory();
- SkASSERT(fDeviceFactory);
- fDeviceFactory->ref();
+ fDeviceFactory = device->getDeviceFactory();
+ SkSafeRef(fDeviceFactory);
this->init(device)->unref();
}
@@ -736,8 +734,9 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
bool isOpaque;
SkBitmap::Config config = resolve_config(this, ir, flags, &isOpaque);
- SkDevice* device = this->createDevice(config, ir.width(), ir.height(),
- isOpaque);
+ SkDevice* device = this->createLayerDevice(config, ir.width(), ir.height(),
+ isOpaque);
+
device->setOrigin(ir.fLeft, ir.fTop);
DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint));
device->unref();
@@ -1176,11 +1175,32 @@ void SkCanvas::setExternalMatrix(const SkMatrix* matrix) {
}
}
-SkDevice* SkCanvas::createDevice(SkBitmap::Config config, int width, int height,
- bool isOpaque) {
- return fDeviceFactory->newDevice(this, config, width, height, isOpaque, true);
+SkDevice* SkCanvas::createLayerDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque) {
+ if (fDeviceFactory) {
+ return fDeviceFactory->newDevice(this, config, width, height,
+ isOpaque, true);
+ } else {
+ return this->getDevice()->createCompatibleDeviceForSaveLayer(
+ config, width, height,
+ isOpaque);
+ }
}
+SkDevice* SkCanvas::createCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque) {
+ SkDevice* device = this->getDevice();
+ if (device) {
+ return device->createCompatibleDevice(config, width, height,
+ isOpaque);
+ } else {
+ return NULL;
+ }
+}
+
+
//////////////////////////////////////////////////////////////////////////////
// These are the virtual drawing methods
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 0c0133558b..ae283b04ef 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -57,7 +57,7 @@ SkDevice::~SkDevice() {
}
SkDeviceFactory* SkDevice::onNewDeviceFactory() {
- return SkNEW(SkRasterDeviceFactory);
+ return NULL;
}
SkDeviceFactory* SkDevice::getDeviceFactory() {
@@ -67,6 +67,27 @@ SkDeviceFactory* SkDevice::getDeviceFactory() {
return fCachedDeviceFactory;
}
+SkDevice* SkDevice::createCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque) {
+ return this->onCreateCompatibleDevice(config, width, height,
+ isOpaque, kGeneral_Usage);
+}
+
+SkDevice* SkDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque) {
+ return this->onCreateCompatibleDevice(config, width, height,
+ isOpaque, kSaveLayer_Usage);
+}
+
+SkDevice* SkDevice::onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage) {
+ return SkNEW_ARGS(SkDevice,(config, width, height, isOpaque));
+}
+
SkMetaData& SkDevice::getMetaData() {
// metadata users are rare, so we lazily allocate it. If that changes we
// can decide to just make it a field in the device (rather than a ptr)
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 189b692dde..cda10d24ff 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -76,7 +76,7 @@ GrTexture* SkGpuDevice::SkAutoCachedTexture::set(SkGpuDevice* device,
fTex = NULL;
} else {
// look it up in our cache
- fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
+ fTex = device->lockCachedTexture(bitmap, sampler, &texture);
}
return texture;
}
@@ -166,7 +166,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
}
SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
- int height, bool isForSaveLayer)
+ int height, Usage usage)
: SkDevice(config, width, height, false /*isOpaque*/) {
fNeedPrepareRenderTarget = false;
fDrawProcs = NULL;
@@ -186,9 +186,11 @@ SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
bm.setConfig(config, width, height);
#if CACHE_LAYER_TEXTURES
-
+ TexType type = (kSaveLayer_Usage == usage) ?
+ kSaveLayerDeviceRenderTarget_TexType :
+ kDeviceRenderTarget_TexType;
fCache = this->lockCachedTexture(bm, GrSamplerState::ClampNoFilter(),
- &fTexture, true, isForSaveLayer);
+ &fTexture, type);
if (fCache) {
SkASSERT(NULL != fTexture);
SkASSERT(NULL != fTexture->asRenderTarget());
@@ -1394,13 +1396,12 @@ bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
const GrSamplerState& sampler,
GrTexture** texture,
- bool forDeviceRenderTarget,
- bool isSaveLayer) {
+ TexType type) {
GrTexture* newTexture = NULL;
GrTextureEntry* entry = NULL;
GrContext* ctx = this->context();
- if (forDeviceRenderTarget) {
+ if (kBitmap_TexType != type) {
const GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit,
kNone_GrAALevel,
@@ -1408,12 +1409,13 @@ SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
bitmap.height(),
SkGr::Bitmap2PixelConfig(bitmap)
};
- if (isSaveLayer) {
+ if (kSaveLayerDeviceRenderTarget_TexType == type) {
// we know layers will only be drawn through drawDevice.
// drawDevice has been made to work with content embedded in a
// larger texture so its okay to use the approximate version.
entry = ctx->findApproximateKeylessTexture(desc);
} else {
+ SkASSERT(kDeviceRenderTarget_TexType == type);
entry = ctx->lockKeylessTexture(desc);
}
} else {
@@ -1446,6 +1448,15 @@ void SkGpuDevice::unlockCachedTexture(TexCache* cache) {
this->context()->unlockTexture((GrTextureEntry*)cache);
}
+SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage) {
+ return SkNEW_ARGS(SkGpuDevice,(this->context(), config,
+ width, height, usage));
+}
+
+
///////////////////////////////////////////////////////////////////////////////
SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
@@ -1499,3 +1510,4 @@ SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
return SkNEW_ARGS(SkGpuDevice, (fContext, fRootRenderTarget));
}
}
+
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index d17f8640c4..67bc64acce 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -423,6 +423,17 @@ void GraphicStackState::updateDrawingState(const GraphicStateEntry& state) {
}
}
+SkDevice* SkPDFDevice::onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage) {
+ SkMatrix initialTransform;
+ initialTransform.reset();
+ SkISize size = SkISize::Make(width, height);
+ return SkNEW_ARGS(SkPDFDevice, (size, size, initialTransform));
+}
+
+
struct ContentEntry {
GraphicStateEntry fState;
SkDynamicMemoryWStream fContent;
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index a7b7f971b9..33f77e485e 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -151,8 +151,3 @@ SkDrawFilter* SkProxyCanvas::setDrawFilter(SkDrawFilter* filter) {
return fProxy->setDrawFilter(filter);
}
-SkDevice* SkProxyCanvas::createDevice(SkBitmap::Config config, int width, int height,
- bool isOpaque) {
- return fProxy->createDevice(config, width, height, isOpaque);
-}
-