From: mike@reedtribe.org Date: Tue, 26 Apr 2011 11:48:33 +0000 (+0000) Subject: make SkDeviceFactory reference counted X-Git-Tag: submit/tizen/20180928.044319~18621 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea4ac97dec2eb291139bd906939e0d2e05cdd7ef;p=platform%2Fupstream%2FlibSkiaSharp.git make SkDeviceFactory reference counted git-svn-id: http://skia.googlecode.com/svn/trunk@1180 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 6b2ee10e75..b1222eb874 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -126,12 +126,15 @@ public: SkDevice* setBitmapDevice(const SkBitmap& bitmap, bool forLayer = false); /** - * Return the current device factory, or NULL. + * Return the current device factory, or NULL. The reference count of + * the returned factory is not changed. */ SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; } /** - * Replace any existing factory with the specified factory. + * 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*); diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 5755e955e0..d9a4fde4c2 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -36,8 +36,9 @@ class SkRegion; to pass into SkCanvas. Doing so will eliminate the need to extend SkCanvas as well. */ -class SK_API SkDeviceFactory { +class SK_API SkDeviceFactory : public SkRefCnt { public: + SkDeviceFactory(); virtual ~SkDeviceFactory(); virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width, int height, bool isOpaque, bool isLayer) = 0; @@ -65,9 +66,12 @@ public: SkDevice(SkCanvas*, const SkBitmap& bitmap, bool forOffscreen); virtual ~SkDevice(); - virtual SkDeviceFactory* getDeviceFactory() { - return SkNEW(SkRasterDeviceFactory); - } + /** + * 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(); enum Capabilities { kGL_Capability = 0x1, //!< mask indicating GL support @@ -247,6 +251,13 @@ public: virtual bool filterTextFlags(const SkPaint& paint, TextFlags*); protected: + /** + * subclasses must 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. + */ + virtual SkDeviceFactory* onNewDeviceFactory(); + /** Update as needed the pixel value in the bitmap, so that the caller can access the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes must remain unchanged. @@ -269,6 +280,8 @@ private: SkBitmap fBitmap; SkIPoint fOrigin; SkMetaData* fMetaData; + + SkDeviceFactory* fCachedDeviceFactory; }; #endif diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index ff1bb0d362..15def87942 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -121,6 +121,9 @@ public: virtual void makeRenderTargetCurrent(); protected: + // override + virtual SkDeviceFactory* onNewDeviceFactory(); + class TexCache; TexCache* lockCachedTexture(const SkBitmap& bitmap, const GrSamplerState& sampler, diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h index ac9ef20fc4..0d06fe6715 100644 --- a/include/pdf/SkPDFDevice.h +++ b/include/pdf/SkPDFDevice.h @@ -61,10 +61,6 @@ public: SkPDFDevice(int width, int height, const SkMatrix& initialTransform); virtual ~SkPDFDevice(); - virtual SkDeviceFactory* getDeviceFactory() { - return SkNEW(SkPDFDeviceFactory); - } - virtual uint32_t getDeviceCapabilities() { return kVector_Capability; } virtual int width() const { return fWidth; }; @@ -138,6 +134,10 @@ public: */ SkStream* content() const; +protected: + // override + virtual SkDeviceFactory* onNewDeviceFactory(); + private: int fWidth; int fHeight; diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 07c2748a7a..dbd4852006 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -417,21 +417,27 @@ SkDevice* SkCanvas::init(SkDevice* device) { } SkCanvas::SkCanvas(SkDeviceFactory* factory) - : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)), - fDeviceFactory(factory) { + : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) { inc_canvas(); - if (!factory) - fDeviceFactory = SkNEW(SkRasterDeviceFactory); + if (factory) { + factory->ref(); + } else { + factory = SkNEW(SkRasterDeviceFactory); + } + fDeviceFactory = factory; this->init(NULL); } SkCanvas::SkCanvas(SkDevice* device) - : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)), - fDeviceFactory(device->getDeviceFactory()) { + : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) { inc_canvas(); + fDeviceFactory = device->getDeviceFactory(); + SkASSERT(fDeviceFactory); + fDeviceFactory->ref(); + this->init(device); } @@ -441,6 +447,9 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap) SkDevice* device = SkNEW_ARGS(SkDevice, (this, bitmap, false)); fDeviceFactory = device->getDeviceFactory(); + SkASSERT(fDeviceFactory); + fDeviceFactory->ref(); + this->init(device)->unref(); } @@ -450,7 +459,7 @@ SkCanvas::~SkCanvas() { this->internalRestore(); // restore the last, since we're going away SkSafeUnref(fBounder); - SkDELETE(fDeviceFactory); + SkSafeUnref(fDeviceFactory); dec_canvas(); } @@ -560,8 +569,7 @@ bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { } SkDeviceFactory* SkCanvas::setDeviceFactory(SkDeviceFactory* factory) { - SkDELETE(fDeviceFactory); - fDeviceFactory = factory; + SkRefCnt_SafeAssign(fDeviceFactory, factory); return factory; } diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 6305e190fe..850a53fd16 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -3,10 +3,31 @@ #include "SkMetaData.h" #include "SkRect.h" -SkDeviceFactory::~SkDeviceFactory() {} +//#define TRACE_FACTORY_LIFETIME + +#ifdef TRACE_FACTORY_LIFETIME + static int gFactoryCounter; +#endif + +SkDeviceFactory::SkDeviceFactory() { +#ifdef TRACE_FACTORY_LIFETIME + SkDebugf("+++ factory index %d\n", gFactoryCounter); + ++gFactoryCounter; +#endif +} + +SkDeviceFactory::~SkDeviceFactory() { +#ifdef TRACE_FACTORY_LIFETIME + --gFactoryCounter; + SkDebugf("--- factory index %d\n", gFactoryCounter); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas), fMetaData(NULL) { fOrigin.setZero(); + fCachedDeviceFactory = NULL; } SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer) @@ -21,10 +42,23 @@ SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer) } } } + fCachedDeviceFactory = NULL; } SkDevice::~SkDevice() { delete fMetaData; + SkSafeUnref(fCachedDeviceFactory); +} + +SkDeviceFactory* SkDevice::onNewDeviceFactory() { + return SkNEW(SkRasterDeviceFactory); +} + +SkDeviceFactory* SkDevice::getDeviceFactory() { + if (NULL == fCachedDeviceFactory) { + fCachedDeviceFactory = this->onNewDeviceFactory(); + } + return fCachedDeviceFactory; } SkMetaData& SkDevice::getMetaData() { diff --git a/src/gpu/SkGpuCanvas.cpp b/src/gpu/SkGpuCanvas.cpp index 9513bbd91f..08cbb32a05 100644 --- a/src/gpu/SkGpuCanvas.cpp +++ b/src/gpu/SkGpuCanvas.cpp @@ -23,14 +23,11 @@ /////////////////////////////////////////////////////////////////////////////// -static SkDeviceFactory* make_df(GrContext* context, - GrRenderTarget* renderTarget) { - return SkNEW_ARGS(SkGpuDeviceFactory, (context, renderTarget)); -} +SkGpuCanvas::SkGpuCanvas(GrContext* context, GrRenderTarget* renderTarget) { + SkDeviceFactory* factory = SkNEW_ARGS(SkGpuDeviceFactory, + (context, renderTarget)); + this->setDeviceFactory(factory)->unref(); -SkGpuCanvas::SkGpuCanvas(GrContext* context, - GrRenderTarget* renderTarget) - : SkCanvas(make_df(context, renderTarget)) { SkASSERT(context); fContext = context; fContext->ref(); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 036d9b5ae9..1c70513245 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -210,6 +210,11 @@ intptr_t SkGpuDevice::getLayerTextureHandle() const { return 0; } } + +SkDeviceFactory* SkGpuDevice::onNewDeviceFactory() { + return SkNEW_ARGS(SkGpuDeviceFactory, (fContext, fRenderTarget)); +} + /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::makeRenderTargetCurrent() { diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index efe7257704..13ffd5b0d4 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -168,6 +168,10 @@ void SkPDFDevice::init() { } } +SkDeviceFactory* SkPDFDevice::onNewDeviceFactory() { + return SkNEW(SkPDFDeviceFactory); +} + void SkPDFDevice::cleanUp() { fGraphicStateResources.unrefAll(); fXObjectResources.unrefAll();