aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkCanvas.h29
-rw-r--r--include/core/SkDevice.h39
-rw-r--r--include/gpu/SkGpuDevice.h21
-rw-r--r--include/pdf/SkPDFDevice.h6
-rwxr-xr-xsamplecode/SampleTextureDomain.cpp2
-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
10 files changed, 166 insertions, 42 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index d5032a76c4..9b96790f3e 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -53,15 +53,19 @@ class SkShape;
*/
class SK_API SkCanvas : public SkRefCnt {
public:
- /** Construct a canvas with the given device factory.
+ /**
+ DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+
+ Construct a canvas with the given device factory.
@param factory Specify the factory for generating additional devices.
The factory may be null, in which case
SkRasterDeviceFactory will be used.
*/
explicit SkCanvas(SkDeviceFactory* factory = NULL);
- /** Construct a canvas with the specified device to draw into. The device
+ /** Construct a canvas with the specified device to draw into. The device
factory will be retrieved from the passed device.
+
@param device Specifies a device for the canvas to draw into.
*/
explicit SkCanvas(SkDevice* device);
@@ -96,13 +100,6 @@ public:
*/
SkDevice* getTopDevice() const;
- /** May be overridden by subclasses. This returns a compatible device
- for this canvas, with the specified config/width/height. If the device
- is raster, the pixels will be allocated automatically.
- */
- virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
- bool isOpaque);
-
/**
* Create a new raster device and make it current. This also returns
* the new device.
@@ -110,18 +107,29 @@ public:
SkDevice* setBitmapDevice(const SkBitmap& bitmap);
/**
+ * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+ *
* Return the current device factory, or NULL. The reference count of
* the returned factory is not changed.
*/
SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; }
/**
+ * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+ *
* Replace any existing factory with the specified factory, unrefing the
* previous (if any), and refing the new one (if any). For convenience,
* the factory parameter is also returned.
*/
SkDeviceFactory* setDeviceFactory(SkDeviceFactory*);
+ /**
+ * Shortcut for getDevice()->createCompatibleDevice(...)
+ */
+ SkDevice* createCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque);
+
///////////////////////////////////////////////////////////////////////////
/**
@@ -834,6 +842,9 @@ private:
friend class SkDrawIter; // needs setupDrawForLayerDevice()
+ SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque);
+
SkDevice* init(SkDevice*);
void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
const SkPaint* paint);
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index ff9c4d1361..59e95e7fdf 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -32,6 +32,8 @@ class SkRegion;
/** \class SkDeviceFactory
+ DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+
Devices that extend SkDevice should also provide a SkDeviceFactory class
to pass into SkCanvas. Doing so will eliminate the need to extend
SkCanvas as well.
@@ -79,12 +81,27 @@ public:
virtual ~SkDevice();
/**
+ * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+ *
* Return the factory that will create this subclass of SkDevice.
* The returned factory is cached by the device, and so its reference count
* is not changed by this call.
*/
SkDeviceFactory* getDeviceFactory();
+ /**
+ * Creates a device that is of the same type as this device (e.g. SW-raster,
+ * GPU, or PDF).
+ *
+ * @param width width of the device to create
+ * @param height height of the device to create
+ * @param isOpaque
+ * @param usage clients should always use the default, kGeneral_Usage.
+ */
+ SkDevice* createCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque);
+
enum Capabilities {
kGL_Capability = 0x1, //!< mask indicating GL support
kVector_Capability = 0x2, //!< mask indicating a vector representation
@@ -264,9 +281,13 @@ public:
protected:
/**
- * subclasses must override this to return a new (or ref'd) instance of
+ * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+ *
+ * subclasses can override this to return a new (or ref'd) instance of
* a device factory that will create this subclass of device. This value
* is cached, so it should get called at most once for a given instance.
+ *
+ * If not overriden then createCompatibleDevice will be used by canvas.
*/
virtual SkDeviceFactory* onNewDeviceFactory();
@@ -276,6 +297,18 @@ protected:
*/
virtual void onAccessBitmap(SkBitmap*);
+ enum Usage {
+ kGeneral_Usage,
+ kSaveLayer_Usage, // <! internal use only
+ };
+ /**
+ * subclasses should override this to implement createCompatibleDevice.
+ */
+ virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage);
+
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
// just for subclasses, to assign a custom pixelref
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
@@ -287,6 +320,10 @@ private:
friend class SkCanvas;
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
+ // just called by SkCanvas for saveLayer
+ SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque);
SkBitmap fBitmap;
SkIPoint fOrigin;
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 4d0efeb511..3a675be24a 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -37,11 +37,12 @@ public:
* New device that will create an offscreen renderTarget based on the
* config, width, height.
*
- * isForSaveLayer is a special flag that should only be set by SkCanvas
+ * usage is a special flag that should only be set by SkCanvas
* internally.
*/
- SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height,
- bool isForSaveLayer = false);
+ SkGpuDevice(GrContext*, SkBitmap::Config,
+ int width, int height,
+ SkDevice::Usage usage = SkDevice::kGeneral_Usage);
/**
* New device that will render to the specified renderTarget.
@@ -132,11 +133,15 @@ protected:
virtual SkDeviceFactory* onNewDeviceFactory();
class TexCache;
+ enum TexType {
+ kBitmap_TexType,
+ kDeviceRenderTarget_TexType,
+ kSaveLayerDeviceRenderTarget_TexType
+ };
TexCache* lockCachedTexture(const SkBitmap& bitmap,
const GrSamplerState& sampler,
GrTexture** texture,
- bool forDeviceRenderTarget = false,
- bool isSaveLayer = false);
+ TexType type = kBitmap_TexType);
void unlockCachedTexture(TexCache*);
class SkAutoCachedTexture {
@@ -192,6 +197,12 @@ private:
GrPaint* grPaint,
bool constantColor);
+ // override from SkDevice
+ virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage);
+
SkDrawProcs* initDrawForText(GrTextContext*);
bool bindDeviceAsTexture(GrPaint* paint);
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 6e4d8db725..2205f6cf58 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -173,6 +173,12 @@ private:
SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
const SkRegion& existingClipRegion);
+ // override from SkDevice
+ virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+ int width, int height,
+ bool isOpaque,
+ Usage usage);
+
void init();
void cleanUp();
void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);
diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp
index 37f584e136..1810723c06 100755
--- a/samplecode/SampleTextureDomain.cpp
+++ b/samplecode/SampleTextureDomain.cpp
@@ -54,7 +54,7 @@ protected:
// Note: GPU-backed bitmaps follow a different rendering path
// when copying from one GPU device to another.
SkRefPtr<SkDevice> primaryDevice(canvas->getDevice());
- SkRefPtr<SkDevice> secondDevice(canvas->createDevice(
+ SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice(
SkBitmap::kARGB_8888_Config, 5, 5, true));
secondDevice->unref();
SkCanvas secondCanvas(secondDevice.get());
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);
-}
-