From: scroggo Date: Wed, 21 Jan 2015 20:09:53 +0000 (-0800) Subject: Make SkStream *not* ref counted. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~3978 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a1193e4b0e34a7e4e1bd33e9708d7341679f8321;p=platform%2Fupstream%2FlibSkiaSharp.git Make SkStream *not* ref counted. SkStream is a stateful object, so it does not make sense for it to have multiple owners. Make SkStream inherit directly from SkNoncopyable. Update methods which previously called SkStream::ref() (e.g. SkImageDecoder::buildTileIndex() and SkFrontBufferedStream::Create(), which required the existing owners to call SkStream::unref()) to take ownership of their SkStream parameters and delete when done (including on failure). Switch all SkAutoTUnrefs to SkAutoTDeletes. In some cases this means heap allocating streams that were previously stack allocated. Respect ownership rules of SkTypeface::CreateFromStream() and SkImageDecoder::buildTileIndex(). Update the comments for exceptional methods which do not affect the ownership of their SkStream parameters (e.g. SkPicture::CreateFromStream() and SkTypeface::Deserialize()) to be explicit about ownership. Remove test_stream_life, which tested that buildTileIndex() behaved correctly when SkStream was a ref counted object. The test does not make sense now that it is not. In SkPDFStream, remove the SkMemoryStream member. Instead of using it, create a new SkMemoryStream to pass to fDataStream (which is now an SkAutoTDelete). Make other pdf rasterizers behave like SkPDFDocumentToBitmap. SkPDFDocumentToBitmap delete the SkStream, so do the same in the following pdf rasterizers: SkPopplerRasterizePDF SkNativeRasterizePDF SkNoRasterizePDF Requires a change to Android, which currently treats SkStreams as ref counted objects. Review URL: https://codereview.chromium.org/849103004 --- diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index e2fcaaa..169a0ee 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -476,7 +476,7 @@ public: return false; } - SkAutoTUnref stream(SkStream::NewFromFile(path)); + SkAutoTDelete stream(SkStream::NewFromFile(path)); if (stream.get() == NULL) { SkDebugf("Could not read %s.\n", path); return false; diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp index 9e21298..01d8c66 100644 --- a/debugger/QT/SkDebuggerGUI.cpp +++ b/debugger/QT/SkDebuggerGUI.cpp @@ -738,13 +738,12 @@ void SkDebuggerGUI::setupDirectoryWidget(const QString& path) { void SkDebuggerGUI::loadPicture(const SkString& fileName) { fFileName = fileName; fLoading = true; - SkStream* stream = SkNEW_ARGS(SkFILEStream, (fileName.c_str())); + SkAutoTDelete stream(SkNEW_ARGS(SkFILEStream, (fileName.c_str()))); SkPicture* picture = SkPicture::CreateFromStream(stream); if (NULL == picture) { QMessageBox::critical(this, "Error loading file", "Couldn't read file, sorry."); - SkSafeUnref(stream); return; } @@ -756,7 +755,6 @@ void SkDebuggerGUI::loadPicture(const SkString& fileName) { fSkipCommands[i] = false; } - SkSafeUnref(stream); SkSafeUnref(picture); fActionProfile.setDisabled(false); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 64b2ec3..fd99435 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -6,6 +6,7 @@ #include "SkOSFile.h" #include "SkPictureRecorder.h" #include "SkRandom.h" +#include "SkStream.h" namespace DM { @@ -48,13 +49,14 @@ Error ImageSrc::draw(SkCanvas* canvas) const { return ""; } // Decode random subsets. This is a little involved. - SkMemoryStream stream(encoded->data(), encoded->size()); - SkAutoTDelete decoder(SkImageDecoder::Factory(&stream)); + SkAutoTDelete stream(new SkMemoryStream(encoded)); + SkAutoTDelete decoder(SkImageDecoder::Factory(stream.get())); if (!decoder) { return SkStringPrintf("Can't find a good decoder for %s.", fPath.c_str()); } + stream->rewind(); int w,h; - if (!decoder->buildTileIndex(&stream, &w, &h) || w*h == 1) { + if (!decoder->buildTileIndex(stream.detach(), &w, &h) || w*h == 1) { return ""; // Not an error. Subset decoding is not always supported. } SkRandom rand; @@ -104,7 +106,7 @@ static const SkRect kSKPViewport = {0,0, 1000,1000}; SKPSrc::SKPSrc(SkString path) : fPath(path) {} Error SKPSrc::draw(SkCanvas* canvas) const { - SkAutoTUnref stream(SkStream::NewFromFile(fPath.c_str())); + SkAutoTDelete stream(SkStream::NewFromFile(fPath.c_str())); if (!stream) { return SkStringPrintf("Couldn't read %s.", fPath.c_str()); } @@ -268,7 +270,7 @@ Error ViaSerialization::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream // Serialize it and then deserialize it. SkDynamicMemoryWStream wStream; pic->serialize(&wStream); - SkAutoTUnref rStream(wStream.detachAsStream()); + SkAutoTDelete rStream(wStream.detachAsStream()); SkAutoTUnref deserialized(SkPicture::CreateFromStream(rStream)); // Turn that deserialized picture into a Src, draw it into our Sink to fill bitmap or stream. diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index e078d7e..df92ff3 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -9,7 +9,6 @@ #include "SkData.h" #include "SkGPipe.h" #include "SkPicture.h" -#include "SkStream.h" #include "gm.h" namespace DM { diff --git a/experimental/PdfViewer/inc/SkPdfRenderer.h b/experimental/PdfViewer/inc/SkPdfRenderer.h index 9fc1ff7..9882a61 100644 --- a/experimental/PdfViewer/inc/SkPdfRenderer.h +++ b/experimental/PdfViewer/inc/SkPdfRenderer.h @@ -35,6 +35,7 @@ public: // TODO(edisonn): replace it with a SkSmartStream which would know to to efficiently // deal with a HTTP stream. // FIXME: Untested. + // Does not affect ownership of SkStream. static SkPdfRenderer* CreateFromStream(SkStream*); // Create a new renderer from a file. static SkPdfRenderer* CreateFromFile(const char* filename); @@ -64,6 +65,7 @@ private: void reportPdfRenderStats(); // Renders a page of a pdf in a bitmap. +// Does not affect ownership of stream. bool SkPDFNativeRenderToBitmap(SkStream* stream, SkBitmap* output, int page = 0, diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h index b92c872..10c8330 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h @@ -69,6 +69,7 @@ public: // TODO(edisonn) should be deprecated // FIXME: Untested. + // Does not affect ownership of stream. SkPdfNativeDoc(SkStream* stream); ~SkPdfNativeDoc(); diff --git a/gm/coloremoji.cpp b/gm/coloremoji.cpp index c083f31..5d8c6ba 100644 --- a/gm/coloremoji.cpp +++ b/gm/coloremoji.cpp @@ -56,13 +56,13 @@ public: protected: void onOnceBeforeDraw() SK_OVERRIDE { SkString filename = GetResourcePath("/Funkster.ttf"); - SkAutoTUnref stream(new SkFILEStream(filename.c_str())); + SkAutoTDelete stream(new SkFILEStream(filename.c_str())); if (!stream->isValid()) { SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n"); return; } - fTypeface = SkTypeface::CreateFromStream(stream); + fTypeface = SkTypeface::CreateFromStream(stream.detach()); } SkString onShortName() SK_OVERRIDE { diff --git a/gm/dcshader.cpp b/gm/dcshader.cpp index 66b0c76..07af695 100644 --- a/gm/dcshader.cpp +++ b/gm/dcshader.cpp @@ -216,13 +216,13 @@ protected: void setFont(SkPaint* paint) SK_OVERRIDE { if (!fTypeface) { SkString filename = GetResourcePath("/Funkster.ttf"); - SkAutoTUnref stream(new SkFILEStream(filename.c_str())); + SkAutoTDelete stream(new SkFILEStream(filename.c_str())); if (!stream->isValid()) { SkDebugf("Could not find Funkster.ttf, please set --resourcePath " "correctly.\n"); return; } - fTypeface.reset(SkTypeface::CreateFromStream(stream)); + fTypeface.reset(SkTypeface::CreateFromStream(stream.detach())); } paint->setTypeface(fTypeface); } diff --git a/gm/dftext.cpp b/gm/dftext.cpp index 8ac36cc..30b82d7 100755 --- a/gm/dftext.cpp +++ b/gm/dftext.cpp @@ -25,13 +25,13 @@ public: protected: void onOnceBeforeDraw() SK_OVERRIDE { SkString filename = GetResourcePath("/Funkster.ttf"); - SkAutoTUnref stream(new SkFILEStream(filename.c_str())); + SkAutoTDelete stream(new SkFILEStream(filename.c_str())); if (!stream->isValid()) { SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n"); return; } - fTypeface = SkTypeface::CreateFromStream(stream); + fTypeface = SkTypeface::CreateFromStream(stream.detach()); } uint32_t onGetFlags() const SK_OVERRIDE { diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h index a0bcd33..4dfd3c2 100644 --- a/include/core/SkImageDecoder.h +++ b/include/core/SkImageDecoder.h @@ -243,6 +243,8 @@ public: * The built index will be saved in the decoder, and the image size will * be returned in width and height. * + * Takes ownership of the SkStreamRewindable, on success or failure. + * * Return true for success or false on failure. */ bool buildTileIndex(SkStreamRewindable*, int *width, int *height); @@ -307,11 +309,9 @@ protected: // must be overridden in subclasses. This guy is called by decode(...) virtual Result onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; - // If the decoder wants to support tiled based decoding, - // this method must be overridden. This guy is called by buildTileIndex(...) - virtual bool onBuildTileIndex(SkStreamRewindable*, int* /*width*/, int* /*height*/) { - return false; - } + // If the decoder wants to support tiled based decoding, this method must be overridden. + // This is called by buildTileIndex(...) + virtual bool onBuildTileIndex(SkStreamRewindable*, int* /*width*/, int* /*height*/); // If the decoder wants to support tiled based decoding, // this method must be overridden. This guy is called by decodeRegion(...) diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 80c3ca3..5b2f7a9 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -80,7 +80,7 @@ public: /** * Recreate a picture that was serialized into a stream. - * @param SkStream Serialized picture data. + * @param SkStream Serialized picture data. Ownership is unchanged by this call. * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the * encoded bitmap data from the stream. * @return A new SkPicture representing the serialized data, or NULL if the stream is diff --git a/include/core/SkStream.h b/include/core/SkStream.h index abd9f92..028c5c1 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -36,17 +36,25 @@ class SkStreamMemory; * no more data (at EOF or hit an error). The caller should *not* call again * in hopes of fulfilling more of the request. */ -class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt +class SK_API SkStream : public SkNoncopyable { public: + virtual ~SkStream() {} + + /** + * @deprecated + * SkStream is no longer ref counted, but we leave this here for staging. + */ + void unref() { + SkDebugf("SkStream is no longer ref counted!"); + } + /** * Attempts to open the specified file, and return a stream to it (using - * mmap if available). On success, the caller must call unref() on the - * returned object. On failure, returns NULL. + * mmap if available). On success, the caller is responsible for deleting. + * On failure, returns NULL. */ static SkStreamAsset* NewFromFile(const char path[]); - SK_DECLARE_INST_COUNT(SkStream) - /** Reads or skips size number of bytes. * If buffer == NULL, skip size bytes, return how many were skipped. * If buffer != NULL, copy size bytes into buffer, return how many were copied. @@ -125,9 +133,6 @@ public: /** Returns the starting address for the data. If this cannot be done, returns NULL. */ //TODO: replace with virtual const SkData* getData() virtual const void* getMemoryBase() { return NULL; } - -private: - typedef SkRefCnt INHERITED; }; /** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */ diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index c2aa543..ecf582b 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -145,6 +145,7 @@ public: to a typeface referring to the same font. If that font is not available, return null. If an instance is returned, the caller is responsible for calling unref() when they are done with it. + Does not affect ownership of SkStream. */ static SkTypeface* Deserialize(SkStream*); @@ -276,6 +277,7 @@ public: * If ttcIndex is not null, it is set to the TrueTypeCollection index * of this typeface within the stream, or 0 if the stream is not a * collection. + * The caller is responsible for deleting the stream. */ SkStream* openStream(int* ttcIndex) const; diff --git a/include/images/SkDecodingImageGenerator.h b/include/images/SkDecodingImageGenerator.h index 6cb39be..0a5ec56 100644 --- a/include/images/SkDecodingImageGenerator.h +++ b/include/images/SkDecodingImageGenerator.h @@ -85,20 +85,8 @@ namespace SkDecodingImageGenerator { * The SkData version of this function is preferred. If the stream * has an underlying SkData (such as a SkMemoryStream) pass that in. * - * This object will unref the stream when done or on failure. Since - * streams have internal state (position), the caller should not pass - * a shared stream in. Pass either a new duplicated stream in or - * transfer ownership of the stream. This factory asserts - * stream->unique(). - * - * For example: - * SkStreamRewindable* stream; - * ... - * SkImageGenerator* gen - * = SkDecodingImageGenerator::Create( - * stream->duplicate(), SkDecodingImageGenerator::Options()); - * ... - * SkDELETE(gen); + * This object, if non-NULL, takes ownership of stream and deletes stream + * upon deletion. If NULL is returned, stream is deleted immediately. * * @param Options (see above) * diff --git a/include/utils/SkFrontBufferedStream.h b/include/utils/SkFrontBufferedStream.h index 68d9861..bfc2728 100644 --- a/include/utils/SkFrontBufferedStream.h +++ b/include/utils/SkFrontBufferedStream.h @@ -26,10 +26,12 @@ public: * @param stream SkStream to buffer. If stream is NULL, NULL is * returned. When this call succeeds (i.e. returns non NULL), * SkFrontBufferedStream is expected to be the only owner of - * stream, so it should be unreffed and no longer used directly. + * stream, so it should no be longer used directly. + * SkFrontBufferedStream will delete stream upon deletion. * @param minBufferSize Minimum size of buffer required. * @return An SkStream that can buffer at least minBufferSize, or - * NULL on failure. + * NULL on failure. The caller is required to delete when finished with + * this object. */ static SkStreamRewindable* Create(SkStream* stream, size_t minBufferSize); }; diff --git a/include/utils/mac/SkCGUtils.h b/include/utils/mac/SkCGUtils.h index a0fe666..7ac0431 100644 --- a/include/utils/mac/SkCGUtils.h +++ b/include/utils/mac/SkCGUtils.h @@ -62,20 +62,17 @@ static inline CGImageRef SkCreateCGImageRef(const SkBitmap& bm) { */ void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y); +/** + * Create an SkBitmap drawing of the encoded PDF document, returning true on + * success. Deletes the stream when finished. + */ bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output); /** - * Return a provider that wraps the specified stream. It will become an - * owner of the stream, so the caller must still manage its ownership. - * - * To hand-off ownership of the stream to the provider, the caller must do - * something like the following: - * - * SkStream* stream = new ...; - * CGDataProviderRef provider = SkStreamToDataProvider(stream); - * stream->unref(); + * Return a provider that wraps the specified stream. It will become the only + * owner of the stream, so the caller must stop referring to the stream. * - * Now when the provider is finally deleted, it will delete the stream. + * When the provider is finally deleted, it will delete the stream. */ CGDataProviderRef SkCreateDataProviderFromStream(SkStream*); diff --git a/samplecode/SampleAnimator.cpp b/samplecode/SampleAnimator.cpp index 50b61ba..a7cc885 100644 --- a/samplecode/SampleAnimator.cpp +++ b/samplecode/SampleAnimator.cpp @@ -51,15 +51,13 @@ void SkAnimatorView::setURIBase(const char dir[]) { } bool SkAnimatorView::decodeFile(const char path[]) { - SkFILEStream* is = new SkFILEStream(path); - SkAutoUnref aur(is); - return is->isValid() && this->decodeStream(is); + SkAutoTDelete is(SkStream::NewFromFile(path)); + return is.get() != NULL && this->decodeStream(is); } bool SkAnimatorView::decodeMemory(const void* buffer, size_t size) { - SkMemoryStream* is = new SkMemoryStream(buffer, size); - SkAutoUnref aur(is); - return this->decodeStream(is); + SkMemoryStream is(buffer, size); + return this->decodeStream(&is); } static const SkDOMNode* find_nodeID(const SkDOM& dom, diff --git a/src/animator/SkAnimateMaker.cpp b/src/animator/SkAnimateMaker.cpp index a3ebb64..2565762 100644 --- a/src/animator/SkAnimateMaker.cpp +++ b/src/animator/SkAnimateMaker.cpp @@ -99,7 +99,7 @@ bool SkAnimateMaker::decodeURI(const char uri[]) { // SkDebugf("animator decode %s\n", uri); // SkStream* stream = SkStream::GetURIStream(fPrefix.c_str(), uri); - SkAutoTUnref stream(SkStream::NewFromFile(uri)); + SkAutoTDelete stream(SkStream::NewFromFile(uri)); if (stream.get()) { bool success = decodeStream(stream); if (hasError() && fError.hasNoun() == false) diff --git a/src/animator/SkAnimator.cpp b/src/animator/SkAnimator.cpp index 1c53e30..f2b7780 100644 --- a/src/animator/SkAnimator.cpp +++ b/src/animator/SkAnimator.cpp @@ -84,7 +84,7 @@ bool SkAnimator::decodeURI(const char uri[]) { // SkDebugf("animator decode %s\n", uri); // SkStream* stream = SkStream::GetURIStream(fMaker->fPrefix.c_str(), uri); - SkAutoTUnref stream(SkStream::NewFromFile(uri)); + SkAutoTDelete stream(SkStream::NewFromFile(uri)); if (stream.get()) { this->setURIBase(uri); return decodeStream(stream); diff --git a/src/animator/SkDrawBitmap.cpp b/src/animator/SkDrawBitmap.cpp index 5349774..f41c152 100644 --- a/src/animator/SkDrawBitmap.cpp +++ b/src/animator/SkDrawBitmap.cpp @@ -189,7 +189,7 @@ void SkImageBaseBitmap::resolve() { fBitmap.reset(); //SkStream* stream = SkStream::GetURIStream(fUriBase, src.c_str()); - SkAutoTUnref stream(SkStream::NewFromFile(src.c_str())); + SkAutoTDelete stream(SkStream::NewFromFile(src.c_str())); if (stream.get()) { SkImageDecoder::DecodeStream(stream, &fBitmap); } diff --git a/src/core/SkFontDescriptor.h b/src/core/SkFontDescriptor.h index 5a6ddd5..aafbe84 100644 --- a/src/core/SkFontDescriptor.h +++ b/src/core/SkFontDescriptor.h @@ -12,11 +12,10 @@ #include "SkString.h" #include "SkTypeface.h" -class SkWStream; - class SkFontDescriptor { public: SkFontDescriptor(SkTypeface::Style = SkTypeface::kNormal); + // Does not affect ownership of SkStream. SkFontDescriptor(SkStream*); void serialize(SkWStream*); @@ -28,7 +27,9 @@ public: const char* getFullName() const { return fFullName.c_str(); } const char* getPostscriptName() const { return fPostscriptName.c_str(); } const char* getFontFileName() const { return fFontFileName.c_str(); } - SkStream* getFontData() const { return fFontData; } + bool hasFontData() const { return fFontData.get() != NULL; } + // Transfers ownership to the caller. + SkStream* transferFontData() { return fFontData.detach(); } int getFontIndex() const { return fFontIndex; } void setFamilyName(const char* name) { fFamilyName.set(name); } @@ -46,7 +47,7 @@ private: SkString fFullName; SkString fPostscriptName; SkString fFontFileName; - SkAutoTUnref fFontData; + SkAutoTDelete fFontData; int fFontIndex; SkTypeface::Style fStyle; diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp index ca29e29..71289a6 100644 --- a/src/core/SkFontMgr.cpp +++ b/src/core/SkFontMgr.cpp @@ -7,10 +7,10 @@ #include "SkFontMgr.h" #include "SkLazyPtr.h" +#include "SkStream.h" #include "SkTypes.h" class SkFontStyle; -class SkStream; class SkTypeface; class SkEmptyFontStyleSet : public SkFontStyleSet { @@ -68,7 +68,8 @@ protected: SkTypeface* onCreateFromData(SkData*, int) const SK_OVERRIDE { return NULL; } - SkTypeface* onCreateFromStream(SkStream*, int) const SK_OVERRIDE { + SkTypeface* onCreateFromStream(SkStream* stream, int) const SK_OVERRIDE { + SkDELETE(stream); return NULL; } SkTypeface* onCreateFromFile(const char[], int) const SK_OVERRIDE { diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index f1d5ab6..0bd641f 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -2084,7 +2084,7 @@ void SkPaint::toString(SkString* str) const { if (typeface) { SkDynamicMemoryWStream ostream; typeface->serialize(&ostream); - SkAutoTUnref istream(ostream.detachAsStream()); + SkAutoTDelete istream(ostream.detachAsStream()); SkFontDescriptor descriptor(istream); str->append("
Font Family Name:
"); diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h index ab78f8a..cada8d1 100644 --- a/src/core/SkPictureData.h +++ b/src/core/SkPictureData.h @@ -58,6 +58,7 @@ struct SkPictInfo { class SkPictureData { public: SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps); + // Does not affect ownership of SkStream. static SkPictureData* CreateFromStream(SkStream*, const SkPictInfo&, SkPicture::InstallPixelRefProc); @@ -79,6 +80,7 @@ public: protected: explicit SkPictureData(const SkPictInfo& info); + // Does not affect ownership of SkStream. bool parseStream(SkStream*, SkPicture::InstallPixelRefProc); bool parseBuffer(SkReadBuffer& buffer); @@ -135,6 +137,7 @@ private: void init(); // these help us with reading/writing + // Does not affect ownership of SkStream. bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc); bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size); void flattenToBuffer(SkWriteBuffer&) const; diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp index 2b190b0..38432c4 100644 --- a/src/core/SkStream.cpp +++ b/src/core/SkStream.cpp @@ -239,7 +239,7 @@ SkStreamAsset* SkFILEStream::duplicate() const { } if (!fName.isEmpty()) { - SkAutoTUnref that(new SkFILEStream(fName.c_str())); + SkAutoTDelete that(new SkFILEStream(fName.c_str())); if (sk_fidentical(that->fFILE, this->fFILE)) { return that.detach(); } @@ -265,7 +265,7 @@ bool SkFILEStream::move(long offset) { } SkStreamAsset* SkFILEStream::fork() const { - SkAutoTUnref that(this->duplicate()); + SkAutoTDelete that(this->duplicate()); that->seek(this->getPosition()); return that.detach(); } @@ -396,7 +396,7 @@ bool SkMemoryStream::move(long offset) { } SkMemoryStream* SkMemoryStream::fork() const { - SkAutoTUnref that(this->duplicate()); + SkAutoTDelete that(this->duplicate()); that->seek(fOffset); return that.detach(); } @@ -741,7 +741,7 @@ public: } SkBlockMemoryStream* fork() const SK_OVERRIDE { - SkAutoTUnref that(this->duplicate()); + SkAutoTDelete that(this->duplicate()); that->fCurrent = this->fCurrent; that->fOffset = this->fOffset; that->fCurrentOffset = this->fCurrentOffset; @@ -827,7 +827,7 @@ SkStreamAsset* SkStream::NewFromFile(const char path[]) { // file access. SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); if (!stream->isValid()) { - stream->unref(); + SkDELETE(stream); stream = NULL; } return stream; @@ -886,7 +886,7 @@ SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) { if (!stream) { return NULL; } - SkAutoTUnref dupStream(stream->duplicate()); + SkAutoTDelete dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index 75ff58e..b86cfa7 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -156,7 +156,7 @@ void SkTypeface::serialize(SkWStream* wstream) const { this->onGetFontDescriptor(&desc, &isLocal); // Embed font data if it's a local font. - if (isLocal && NULL == desc.getFontData()) { + if (isLocal && !desc.hasFontData()) { int ttcIndex; desc.setFontData(this->onOpenStream(&ttcIndex)); desc.setFontIndex(ttcIndex); @@ -170,7 +170,7 @@ void SkTypeface::serializeForcingEmbedding(SkWStream* wstream) const { this->onGetFontDescriptor(&desc, &ignoredIsLocal); // Always embed font data. - if (NULL == desc.getFontData()) { + if (!desc.hasFontData()) { int ttcIndex; desc.setFontData(this->onOpenStream(&ttcIndex)); desc.setFontIndex(ttcIndex); @@ -180,7 +180,7 @@ void SkTypeface::serializeForcingEmbedding(SkWStream* wstream) const { SkTypeface* SkTypeface::Deserialize(SkStream* stream) { SkFontDescriptor desc(stream); - SkStream* data = desc.getFontData(); + SkStream* data = desc.transferFontData(); if (data) { SkTypeface* typeface = SkTypeface::CreateFromStream(data, desc.getFontIndex()); if (typeface) { diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp index df2cdd9..c1105a2 100644 --- a/src/device/xps/SkXPSDevice.cpp +++ b/src/device/xps/SkXPSDevice.cpp @@ -401,7 +401,7 @@ static HRESULT subset_typeface(SkXPSDevice::TypefaceUse* current) { fontPackageBuffer.realloc(bytesWritten); } - SkAutoTUnref newStream(new SkMemoryStream()); + SkAutoTDelete newStream(new SkMemoryStream()); newStream->setMemoryOwned(fontPackageBuffer.detach(), bytesWritten + extra); SkTScopedComPtr newIStream; diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp index a3989fc..c1d531d 100644 --- a/src/fonts/SkFontMgr_fontconfig.cpp +++ b/src/fonts/SkFontMgr_fontconfig.cpp @@ -296,6 +296,7 @@ protected: SkTypeface* onCreateFromData(SkData*, int ttcIndex) const SK_OVERRIDE { return NULL; } SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { + SkAutoTDelete streamDeleter(stream); const size_t length = stream->getLength(); if (!length) { return NULL; @@ -311,13 +312,13 @@ protected: return NULL; } - SkTypeface* face = FontConfigTypeface::Create(style, isFixedWidth, stream); + SkTypeface* face = FontConfigTypeface::Create(style, isFixedWidth, streamDeleter.detach()); return face; } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; + SkAutoTDelete stream(SkStream::NewFromFile(path)); + return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL; } virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], diff --git a/src/fonts/SkFontMgr_indirect.cpp b/src/fonts/SkFontMgr_indirect.cpp index c438623..6f94dfd 100644 --- a/src/fonts/SkFontMgr_indirect.cpp +++ b/src/fonts/SkFontMgr_indirect.cpp @@ -213,19 +213,19 @@ SkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& i // No exact match, but did find a data match. if (dataTypeface.get() != NULL) { - SkAutoTUnref stream(dataTypeface->openStream(NULL)); + SkAutoTDelete stream(dataTypeface->openStream(NULL)); if (stream.get() != NULL) { - return fImpl->createFromStream(stream.get(), dataTypefaceIndex); + return fImpl->createFromStream(stream.detach(), dataTypefaceIndex); } } // No data match, request data and add entry. - SkAutoTUnref stream(fProxy->getData(id.fDataId)); + SkAutoTDelete stream(fProxy->getData(id.fDataId)); if (stream.get() == NULL) { return NULL; } - SkAutoTUnref typeface(fImpl->createFromStream(stream, id.fTtcIndex)); + SkAutoTUnref typeface(fImpl->createFromStream(stream.detach(), id.fTtcIndex)); if (typeface.get() == NULL) { return NULL; } diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index e46f336..a915214 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -125,7 +125,7 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, } int faceIndex; - SkAutoTUnref fontStream(typeface->openStream(&faceIndex)); + SkAutoTDelete fontStream(typeface->openStream(&faceIndex)); const size_t fontDataLength = fontStream->getLength(); if (0 == fontDataLength) { diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp index baa112c..e7a775e 100644 --- a/src/images/SkDecodingImageGenerator.cpp +++ b/src/images/SkDecodingImageGenerator.cpp @@ -24,11 +24,11 @@ class DecodingImageGenerator : public SkImageGenerator { public: virtual ~DecodingImageGenerator(); - SkData* fData; - SkStreamRewindable* fStream; - const SkImageInfo fInfo; - const int fSampleSize; - const bool fDitherImage; + SkData* fData; + SkAutoTDelete fStream; + const SkImageInfo fInfo; + const int fSampleSize; + const bool fDitherImage; DecodingImageGenerator(SkData* data, SkStreamRewindable* stream, @@ -128,7 +128,6 @@ DecodingImageGenerator::DecodingImageGenerator( DecodingImageGenerator::~DecodingImageGenerator() { SkSafeUnref(fData); - fStream->unref(); } SkData* DecodingImageGenerator::onRefEncodedData() { @@ -227,7 +226,7 @@ SkImageGenerator* CreateDecodingImageGenerator( SkStreamRewindable* stream, const SkDecodingImageGenerator::Options& opts) { SkASSERT(stream); - SkAutoTUnref autoStream(stream); // always unref this. + SkAutoTDelete autoStream(stream); // always delete this SkAssertResult(autoStream->rewind()); SkAutoTDelete decoder(SkImageDecoder::Factory(autoStream)); if (NULL == decoder.get()) { @@ -280,7 +279,6 @@ SkImageGenerator* SkDecodingImageGenerator::Create( } SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); SkASSERT(stream != NULL); - SkASSERT(stream->unique()); return CreateDecodingImageGenerator(data, stream, opts); } @@ -288,9 +286,7 @@ SkImageGenerator* SkDecodingImageGenerator::Create( SkStreamRewindable* stream, const SkDecodingImageGenerator::Options& opts) { SkASSERT(stream != NULL); - SkASSERT(stream->unique()); - if ((stream == NULL) || !stream->unique()) { - SkSafeUnref(stream); + if (stream == NULL) { return NULL; } return CreateDecodingImageGenerator(NULL, stream, opts); diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp index 596d05e..89a4705 100644 --- a/src/images/SkImageDecoder.cpp +++ b/src/images/SkImageDecoder.cpp @@ -158,6 +158,13 @@ bool SkImageDecoder::buildTileIndex(SkStreamRewindable* stream, int *width, int return this->onBuildTileIndex(stream, width, height); } +bool SkImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int* /*width*/, + int* /*height*/) { + SkDELETE(stream); + return false; +} + + bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, int dstX, int dstY, int width, int height, int srcX, int srcY) { @@ -212,7 +219,7 @@ bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pre SkASSERT(file); SkASSERT(bm); - SkAutoTUnref stream(SkStream::NewFromFile(file)); + SkAutoTDelete stream(SkStream::NewFromFile(file)); if (stream.get()) { if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) { bm->pixelRef()->setURI(file); diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index 8c9d267..e0722e1 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -105,8 +105,10 @@ static void initialize_info(jpeg_decompress_struct* cinfo, skjpeg_source_mgr* sr #ifdef SK_BUILD_FOR_ANDROID class SkJPEGImageIndex { public: + // Takes ownership of stream. SkJPEGImageIndex(SkStreamRewindable* stream, SkImageDecoder* decoder) : fSrcMgr(stream, decoder) + , fStream(stream) , fInfoInitialized(false) , fHuffmanCreated(false) , fDecompressStarted(false) @@ -206,6 +208,7 @@ public: private: skjpeg_source_mgr fSrcMgr; + SkAutoTDelete fStream; jpeg_decompress_struct fCInfo; huffman_index fHuffmanIndex; bool fInfoInitialized; diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp index c3bba6e..f9ef6b7 100644 --- a/src/images/SkImageDecoder_libpng.cpp +++ b/src/images/SkImageDecoder_libpng.cpp @@ -53,13 +53,13 @@ SK_CONF_DECLARE(bool, c_suppressPNGImageDecoderWarnings, class SkPNGImageIndex { public: + // Takes ownership of stream. SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop info_ptr) : fStream(stream) , fPng_ptr(png_ptr) , fInfo_ptr(info_ptr) , fColorType(kUnknown_SkColorType) { SkASSERT(stream != NULL); - stream->ref(); } ~SkPNGImageIndex() { if (fPng_ptr) { @@ -67,7 +67,7 @@ public: } } - SkAutoTUnref fStream; + SkAutoTDelete fStream; png_structp fPng_ptr; png_infop fInfo_ptr; SkColorType fColorType; @@ -718,6 +718,7 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, #ifdef SK_BUILD_FOR_ANDROID bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *width, int *height) { + SkAutoTDelete streamDeleter(sk_stream); png_structp png_ptr; png_infop info_ptr; @@ -743,7 +744,7 @@ bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *wid if (fImageIndex) { SkDELETE(fImageIndex); } - fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (sk_stream, png_ptr, info_ptr)); + fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (streamDeleter.detach(), png_ptr, info_ptr)); return true; } diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp index c56933d..5ac647a 100644 --- a/src/images/SkImageDecoder_libwebp.cpp +++ b/src/images/SkImageDecoder_libwebp.cpp @@ -95,14 +95,10 @@ static bool webp_parse_header(SkStream* stream, int* width, int* height, int* al class SkWEBPImageDecoder: public SkImageDecoder { public: SkWEBPImageDecoder() { - fInputStream = NULL; fOrigWidth = 0; fOrigHeight = 0; fHasAlpha = 0; } - virtual ~SkWEBPImageDecoder() { - SkSafeUnref(fInputStream); - } Format getFormat() const SK_OVERRIDE { return kWEBP_Format; @@ -125,7 +121,7 @@ private: bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height); - SkStream* fInputStream; + SkAutoTDelete fInputStream; int fOrigWidth; int fOrigHeight; int fHasAlpha; @@ -316,6 +312,7 @@ bool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap, int width, int bool SkWEBPImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width, int *height) { + SkAutoTDelete streamDeleter(stream); int origWidth, origHeight, hasAlpha; if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { return false; @@ -329,7 +326,7 @@ bool SkWEBPImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, *width = origWidth; *height = origHeight; - SkRefCnt_SafeAssign(this->fInputStream, stream); + this->fInputStream.reset(streamDeleter.detach()); this->fOrigWidth = origWidth; this->fOrigHeight = origHeight; this->fHasAlpha = hasAlpha; diff --git a/src/images/SkJpegUtility.cpp b/src/images/SkJpegUtility.cpp index e17b55b..937c5ec 100644 --- a/src/images/SkJpegUtility.cpp +++ b/src/images/SkJpegUtility.cpp @@ -96,7 +96,7 @@ static void sk_term_source(j_decompress_ptr /*cinfo*/) {} /////////////////////////////////////////////////////////////////////////////// skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder) - : fStream(SkRef(stream)) + : fStream(stream) , fDecoder(decoder) { init_source = sk_init_source; @@ -110,10 +110,6 @@ skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder) // SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize); } -skjpeg_source_mgr::~skjpeg_source_mgr() { - SkSafeUnref(fStream); -} - /////////////////////////////////////////////////////////////////////////////// static void sk_init_destination(j_compress_ptr cinfo) { diff --git a/src/images/SkJpegUtility.h b/src/images/SkJpegUtility.h index 69092ef..1a763f8 100644 --- a/src/images/SkJpegUtility.h +++ b/src/images/SkJpegUtility.h @@ -35,9 +35,8 @@ void skjpeg_error_exit(j_common_ptr cinfo); */ struct skjpeg_source_mgr : jpeg_source_mgr { skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder); - ~skjpeg_source_mgr(); - // fStream is ref'ed and unref'ed + // Unowned. SkStream* fStream; // Unowned pointer to the decoder, used to check if the decoding process // has been cancelled. diff --git a/src/images/SkMovie.cpp b/src/images/SkMovie.cpp index 9a2a71c..2a1339f 100644 --- a/src/images/SkMovie.cpp +++ b/src/images/SkMovie.cpp @@ -90,6 +90,6 @@ SkMovie* SkMovie::DecodeMemory(const void* data, size_t length) { } SkMovie* SkMovie::DecodeFile(const char path[]) { - SkAutoTUnref stream(SkStream::NewFromFile(path)); + SkAutoTDelete stream(SkStream::NewFromFile(path)); return stream.get() ? SkMovie::DecodeStream(stream) : NULL; } diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index a093f62..de61326 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -158,7 +158,7 @@ static SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen, // if the data was NUL terminated so that we can use strstr() to search it. // Make as few copies as possible given these constraints. SkDynamicMemoryWStream dynamicStream; - SkAutoTUnref staticStream; + SkAutoTDelete staticStream; SkData* data = NULL; const uint8_t* src; size_t srcLen; @@ -586,7 +586,7 @@ static size_t get_subset_font_stream(const char* fontName, const SkTDArray& subset, SkPDFStream** fontStream) { int ttcIndex; - SkAutoTUnref fontData(typeface->openStream(&ttcIndex)); + SkAutoTDelete fontData(typeface->openStream(&ttcIndex)); SkASSERT(fontData.get()); size_t fontSize = fontData->getLength(); @@ -1091,7 +1091,7 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, fontStream.reset(rawStream); } else { int ttcIndex; - SkAutoTUnref fontData( + SkAutoTDelete fontData( typeface()->openStream(&ttcIndex)); fontStream.reset(new SkPDFStream(fontData.get())); fontSize = fontData->getLength(); @@ -1108,7 +1108,7 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, case SkAdvancedTypefaceMetrics::kCFF_Font: case SkAdvancedTypefaceMetrics::kType1CID_Font: { int ttcIndex; - SkAutoTUnref fontData(typeface()->openStream(&ttcIndex)); + SkAutoTDelete fontData(typeface()->openStream(&ttcIndex)); SkAutoTUnref fontStream( new SkPDFStream(fontData.get())); addResource(fontStream.get()); @@ -1238,7 +1238,7 @@ bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { size_t header SK_INIT_TO_AVOID_WARNING; size_t data SK_INIT_TO_AVOID_WARNING; size_t trailer SK_INIT_TO_AVOID_WARNING; - SkAutoTUnref rawFontData(typeface()->openStream(&ttcIndex)); + SkAutoTDelete rawFontData(typeface()->openStream(&ttcIndex)); SkAutoTUnref fontData(handle_type1_stream(rawFontData.get(), &header, &data, &trailer)); if (fontData.get() == NULL) { @@ -1405,7 +1405,7 @@ bool SkPDFType3Font::populate(uint16_t glyphID) { SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(), &content); } - SkAutoTUnref glyphStream(new SkMemoryStream()); + SkAutoTDelete glyphStream(new SkMemoryStream()); glyphStream->setData(content.copyToData())->unref(); SkAutoTUnref glyphDescription( diff --git a/src/pdf/SkPDFFormXObject.cpp b/src/pdf/SkPDFFormXObject.cpp index 1635b0f..2a0f530 100644 --- a/src/pdf/SkPDFFormXObject.cpp +++ b/src/pdf/SkPDFFormXObject.cpp @@ -25,7 +25,7 @@ SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) { SkPDFResourceDict* resourceDict = device->getResourceDict(); resourceDict->getReferencedResources(emptySet, &fResources, false); - SkAutoTUnref content(device->content()); + SkAutoTDelete content(device->content()); setData(content.get()); SkAutoTUnref bboxArray(device->copyMediaBox()); diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp index 65454fa..5dc6bab 100644 --- a/src/pdf/SkPDFImage.cpp +++ b/src/pdf/SkPDFImage.cpp @@ -239,40 +239,41 @@ static SkStream* extract_image_data(const SkBitmap& bitmap, } return NULL; } - bool isOpaque = true; - bool transparent = extractAlpha; - SkStream* stream = NULL; SkAutoLockPixels lock(bitmap); if (NULL == bitmap.getPixels()) { return NULL; } + bool isOpaque = true; + bool transparent = extractAlpha; + SkAutoTDelete stream; + switch (colorType) { case kIndex_8_SkColorType: if (!extractAlpha) { - stream = extract_index8_image(bitmap, srcRect); + stream.reset(extract_index8_image(bitmap, srcRect)); } break; case kARGB_4444_SkColorType: - stream = extract_argb4444_data(bitmap, srcRect, extractAlpha, - &isOpaque, &transparent); + stream.reset(extract_argb4444_data(bitmap, srcRect, extractAlpha, + &isOpaque, &transparent)); break; case kRGB_565_SkColorType: if (!extractAlpha) { - stream = extract_rgb565_image(bitmap, srcRect); + stream.reset(extract_rgb565_image(bitmap, srcRect)); } break; case kN32_SkColorType: - stream = extract_argb8888_data(bitmap, srcRect, extractAlpha, - &isOpaque, &transparent); + stream.reset(extract_argb8888_data(bitmap, srcRect, extractAlpha, + &isOpaque, &transparent)); break; case kAlpha_8_SkColorType: if (!extractAlpha) { - stream = create_black_image(); + stream.reset(create_black_image()); } else { - stream = extract_a8_alpha(bitmap, srcRect, - &isOpaque, &transparent); + stream.reset(extract_a8_alpha(bitmap, srcRect, + &isOpaque, &transparent)); } break; default: @@ -283,10 +284,9 @@ static SkStream* extract_image_data(const SkBitmap& bitmap, *isTransparent = transparent; } if (extractAlpha && (transparent || isOpaque)) { - SkSafeUnref(stream); return NULL; } - return stream; + return stream.detach(); } static SkPDFArray* make_indexed_color_space(SkColorTable* table) { @@ -468,7 +468,7 @@ SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap, } bool isTransparent = false; - SkAutoTUnref alphaData; + SkAutoTDelete alphaData; if (!bitmap.isOpaque()) { // Note that isOpaque is not guaranteed to return false for bitmaps // with alpha support but a completely opaque alpha channel, @@ -639,7 +639,7 @@ bool SkPDFImage::populate(SkPDFCatalog* catalog) { } // Fallback method if (!fStreamValid) { - SkAutoTUnref stream( + SkAutoTDelete stream( extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL)); this->setData(stream); fStreamValid = true; diff --git a/src/pdf/SkPDFImage.h b/src/pdf/SkPDFImage.h index 5c026da..a4bc548 100644 --- a/src/pdf/SkPDFImage.h +++ b/src/pdf/SkPDFImage.h @@ -82,6 +82,7 @@ private: * @param stream The image stream. May be NULL. Otherwise, this * (instead of the input bitmap) will be used as the * PDF's content stream, possibly with lossless encoding. + * Will be duplicated, and left in indeterminate state. * @param bitmap The image. If a stream is not given, its color data * will be used as the image. If a stream is given, this * is used for configuration only. diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp index 2a144a6..1b9d9eb 100644 --- a/src/pdf/SkPDFShader.cpp +++ b/src/pdf/SkPDFShader.cpp @@ -737,7 +737,7 @@ SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() { SkAutoTUnref luminosityShader(SkPDFShader::GetPDFShaderByState( fShaderState->CreateAlphaToLuminosityState())); - SkAutoTUnref alphaStream(create_pattern_fill_content(-1, bbox)); + SkAutoTDelete alphaStream(create_pattern_fill_content(-1, bbox)); SkAutoTUnref resources(get_gradient_resource_dict(luminosityShader, NULL)); @@ -764,7 +764,7 @@ SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) fResourceDict.reset( get_gradient_resource_dict(fColorShader.get(), alphaGs.get())); - SkAutoTUnref colorStream( + SkAutoTDelete colorStream( create_pattern_fill_content(0, bbox)); setData(colorStream.get()); @@ -1131,7 +1131,7 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) } // Put the canvas into the pattern stream (fContent). - SkAutoTUnref content(pattern.content()); + SkAutoTDelete content(pattern.content()); setData(content.get()); SkPDFResourceDict* resourceDict = pattern.getResourceDict(); resourceDict->getReferencedResources(fResources, &fResources, false); diff --git a/src/pdf/SkPDFStream.cpp b/src/pdf/SkPDFStream.cpp index 837de7a..5eaa6c2 100644 --- a/src/pdf/SkPDFStream.cpp +++ b/src/pdf/SkPDFStream.cpp @@ -61,25 +61,19 @@ void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { SkPDFStream::SkPDFStream() : fState(kUnused_State) {} void SkPDFStream::setData(SkData* data) { - fMemoryStream.setData(data); - if (&fMemoryStream != fDataStream.get()) { - fDataStream.reset(SkRef(&fMemoryStream)); - } + // FIXME: Don't swap if the data is the same. + fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data))); } void SkPDFStream::setData(SkStream* stream) { // Code assumes that the stream starts at the beginning and is rewindable. - if (&fMemoryStream == fDataStream.get()) { - SkASSERT(&fMemoryStream != stream); - fMemoryStream.setData(NULL); - } - SkASSERT(0 == fMemoryStream.getLength()); if (stream) { // SkStreamRewindableFromSkStream will try stream->duplicate(). fDataStream.reset(SkStreamRewindableFromSkStream(stream)); SkASSERT(fDataStream.get()); } else { - fDataStream.reset(SkRef(&fMemoryStream)); + // Use an empty memory stream. + fDataStream.reset(SkNEW(SkMemoryStream)); } } @@ -97,7 +91,7 @@ bool SkPDFStream::populate(SkPDFCatalog* catalog) { SkFlate::Deflate(fDataStream.get(), &compressedData)); SkAssertResult(fDataStream->rewind()); if (compressedData.getOffset() < this->dataSize()) { - SkAutoTUnref compressed( + SkAutoTDelete compressed( compressedData.detachAsStream()); this->setData(compressed.get()); insertName("Filter", "FlateDecode"); diff --git a/src/pdf/SkPDFStream.h b/src/pdf/SkPDFStream.h index 586b2e8..cf9316f 100644 --- a/src/pdf/SkPDFStream.h +++ b/src/pdf/SkPDFStream.h @@ -93,10 +93,7 @@ private: // Mutex guards fState, fDataStream, and fSubstitute in public interface. SkMutex fMutex; - SkMemoryStream fMemoryStream; // Used by fDataStream when - // fDataStream needs to be backed - // by SkData. - SkAutoTUnref fDataStream; + SkAutoTDelete fDataStream; SkAutoTUnref fSubstitute; typedef SkPDFDict INHERITED; diff --git a/src/ports/SkFontConfigTypeface.h b/src/ports/SkFontConfigTypeface.h index fcbc16f..821f490 100644 --- a/src/ports/SkFontConfigTypeface.h +++ b/src/ports/SkFontConfigTypeface.h @@ -15,7 +15,7 @@ class SkFontDescriptor; class FontConfigTypeface : public SkTypeface_FreeType { SkFontConfigInterface::FontIdentity fIdentity; SkString fFamilyName; - SkStream* fLocalStream; + SkAutoTDelete fLocalStream; public: static FontConfigTypeface* Create(const SkFontStyle& style, @@ -29,16 +29,12 @@ public: return SkNEW_ARGS(FontConfigTypeface, (style, fixedWidth, localStream)); } - virtual ~FontConfigTypeface() { - SkSafeUnref(fLocalStream); - } - const SkFontConfigInterface::FontIdentity& getIdentity() const { return fIdentity; } const char* getFamilyName() const { return fFamilyName.c_str(); } - SkStream* getLocalStream() const { return fLocalStream; } + SkStream* getLocalStream() const { return fLocalStream.get(); } bool isFamilyName(const char* name) const { return fFamilyName.equals(name); @@ -60,10 +56,9 @@ protected: , fLocalStream(NULL) {} FontConfigTypeface(const SkFontStyle& style, bool fixedWidth, SkStream* localStream) - : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) { + : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) + , fLocalStream(localStream) { // we default to empty fFamilyName and fIdentity - fLocalStream = localStream; - SkSafeRef(localStream); } void onGetFamilyName(SkString* familyName) const SK_OVERRIDE; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index ce762d8..72fe8f6 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -233,18 +233,15 @@ private: /////////////////////////////////////////////////////////////////////////// struct SkFaceRec { - SkFaceRec* fNext; - FT_Face fFace; - FT_StreamRec fFTStream; - SkStream* fSkStream; - uint32_t fRefCnt; - uint32_t fFontID; - - // assumes ownership of the stream, will call unref() when its done + SkFaceRec* fNext; + FT_Face fFace; + FT_StreamRec fFTStream; + SkAutoTDelete fSkStream; + uint32_t fRefCnt; + uint32_t fFontID; + + // assumes ownership of the stream, will delete when its done SkFaceRec(SkStream* strm, uint32_t fontID); - ~SkFaceRec() { - fSkStream->unref(); - } }; extern "C" { diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp index 32e9f80..4c577d8 100644 --- a/src/ports/SkFontHost_fontconfig.cpp +++ b/src/ports/SkFontHost_fontconfig.cpp @@ -132,7 +132,7 @@ SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { // should have been provided by CreateFromStream() *ttcIndex = 0; - SkAutoTUnref dupStream(stream->duplicate()); + SkAutoTDelete dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } @@ -148,13 +148,10 @@ SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkAutoTMalloc allocMemory(length); stream->rewind(); if (length == stream->read(allocMemory.get(), length)) { - SkAutoTUnref copyStream(new SkMemoryStream()); + SkAutoTDelete copyStream(new SkMemoryStream()); copyStream->setMemoryOwned(allocMemory.detach(), length); return copyStream.detach(); } - - stream->rewind(); - stream->ref(); } else { SkAutoTUnref fci(RefFCI()); if (NULL == fci.get()) { diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp index ec8e338..b6fab62 100644 --- a/src/ports/SkFontHost_linux.cpp +++ b/src/ports/SkFontHost_linux.cpp @@ -139,7 +139,7 @@ protected: private: SkString fPath; - const SkAutoTUnref fStream; + const SkAutoTDelete fStream; typedef SkTypeface_Custom INHERITED; }; @@ -283,13 +283,12 @@ protected: } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(new SkMemoryStream(data)); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(new SkMemoryStream(data), ttcIndex); } SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { + SkAutoTDelete streamDeleter(stream); if (NULL == stream || stream->getLength() <= 0) { - SkDELETE(stream); return NULL; } @@ -298,15 +297,15 @@ protected: SkString name; if (fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) { return SkNEW_ARGS(SkTypeface_Stream, (style, isFixedPitch, false, name, - stream, ttcIndex)); + streamDeleter.detach(), ttcIndex)); } else { return NULL; } } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; + SkAutoTDelete stream(SkStream::NewFromFile(path)); + return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL; } virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], @@ -341,7 +340,7 @@ private: while (iter.next(&name, false)) { SkString filename(SkOSPath::Join(directory.c_str(), name.c_str())); - SkAutoTUnref stream(SkStream::NewFromFile(filename.c_str())); + SkAutoTDelete stream(SkStream::NewFromFile(filename.c_str())); if (!stream.get()) { SkDebugf("---- failed to open <%s>\n", filename.c_str()); continue; diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 1ec2bb5..70f3ddf 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -1924,6 +1924,7 @@ static HANDLE activate_font(SkData* fontData) { return fontHandle; } +// Does not affect ownership of stream. static SkTypeface* create_from_stream(SkStream* stream) { // Create a unique and unpredictable font name. // Avoids collisions and access from CSS. @@ -2481,19 +2482,18 @@ protected: } SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { + SkAutoTDelete streamDeleter(stream); return create_from_stream(stream); } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { // could be in base impl - SkAutoTUnref stream(SkNEW_ARGS(SkMemoryStream, (data))); - return this->createFromStream(stream); + return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data))); } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { // could be in base impl - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return this->createFromStream(stream); + return this->createFromStream(SkStream::NewFromFile(path)); } virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp index 794790b..ce93194 100644 --- a/src/ports/SkFontMgr_android.cpp +++ b/src/ports/SkFontMgr_android.cpp @@ -104,7 +104,7 @@ public: bool isFixedPitch, const SkString& familyName) : INHERITED(index, style, isFixedPitch, familyName) - , fStream(SkRef(stream)) { } + , fStream(stream) { } virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const SK_OVERRIDE { @@ -121,7 +121,7 @@ public: } private: - SkAutoTUnref fStream; + SkAutoTDelete fStream; typedef SkTypeface_Android INHERITED; }; @@ -152,7 +152,7 @@ public: SkString pathName; get_path_for_sys_fonts(basePath, fontFile.fFileName, &pathName); - SkAutoTUnref stream(SkStream::NewFromFile(pathName.c_str())); + SkAutoTDelete stream(SkStream::NewFromFile(pathName.c_str())); if (!stream.get()) { DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathName.c_str())); continue; @@ -409,23 +409,23 @@ protected: } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(new SkMemoryStream(data)); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(new SkMemoryStream(data), ttcIndex); } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL; + SkAutoTDelete stream(SkStream::NewFromFile(path)); + return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL; } SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { + SkAutoTDelete streamDeleter(stream); bool isFixedPitch; SkFontStyle style; SkString name; if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) { return NULL; } - return SkNEW_ARGS(SkTypeface_AndroidStream, (stream, ttcIndex, + return SkNEW_ARGS(SkTypeface_AndroidStream, (streamDeleter.detach(), ttcIndex, style, isFixedPitch, name)); } diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp index b5e4eae..28df5d4 100644 --- a/src/ports/SkFontMgr_fontconfig.cpp +++ b/src/ports/SkFontMgr_fontconfig.cpp @@ -378,7 +378,7 @@ public: /** @param stream does not take ownership of the reference, does take ownership of the stream.*/ SkTypeface_stream(const SkFontStyle& style, bool fixedWidth, int index, SkStreamAsset* stream) : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) - , fStream(SkRef(stream)) + , fStream(stream) , fIndex(index) { }; @@ -397,7 +397,7 @@ public: } private: - SkAutoTUnref fStream; + SkAutoTDelete fStream; int fIndex; typedef SkTypeface_FreeType INHERITED; @@ -809,8 +809,8 @@ protected: return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style); } - /** @param stream does not take ownership of the reference. */ - SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE { + SkTypeface* onCreateFromStream(SkStream* inputStream, int ttcIndex) const SK_OVERRIDE { + SkAutoTDelete stream(inputStream); const size_t length = stream->getLength(); if (length <= 0 || (1u << 30) < length) { return NULL; @@ -823,17 +823,15 @@ protected: } return SkNEW_ARGS(SkTypeface_stream, (style, isFixedWidth, ttcIndex, - static_cast(stream))); + static_cast(stream.detach()))); } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(SkNEW_ARGS(SkMemoryStream, (data))); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data)), ttcIndex); } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(SkStream::NewFromFile(path), ttcIndex); } virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp index e7ea980..31c1d3f 100644 --- a/src/ports/SkFontMgr_win_dw.cpp +++ b/src/ports/SkFontMgr_win_dw.cpp @@ -34,6 +34,7 @@ public: UINT32 fontFileReferenceKeySize, IDWriteFontFileStream** fontFileStream); + // Takes ownership of stream. static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFileLoader) { *streamFontFileLoader = new StreamFontFileLoader(stream); if (NULL == streamFontFileLoader) { @@ -42,10 +43,10 @@ public: return S_OK; } - SkAutoTUnref fStream; + SkAutoTDelete fStream; private: - StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream)) { } + StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(stream) { } virtual ~StreamFontFileLoader() { } ULONG fRefCount; @@ -80,7 +81,7 @@ HRESULT StreamFontFileLoader::CreateStreamFromKey( IDWriteFontFileStream** fontFileStream) { SkTScopedComPtr stream; - HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream)); + HR(SkDWriteFontFileStreamWrapper::Create(fStream->duplicate(), &stream)); *fontFileStream = stream.release(); return S_OK; } @@ -535,6 +536,7 @@ private: SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcIndex) const { SkTScopedComPtr fontFileLoader; + // This transfers ownership of stream to the new object. HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get())); SkAutoIDWriteUnregister autoUnregisterFontFileLoader( @@ -580,13 +582,11 @@ SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcI } SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) const { - SkAutoTUnref stream(SkNEW_ARGS(SkMemoryStream, (data))); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data)), ttcIndex); } SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) const { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return this->createFromStream(stream, ttcIndex); + return this->createFromStream(SkStream::NewFromFile(path), ttcIndex); } HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[], diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp index 069cf7f..e5ad6da 100644 --- a/src/ports/SkImageDecoder_empty.cpp +++ b/src/ports/SkImageDecoder_empty.cpp @@ -11,10 +11,9 @@ #include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "SkMovie.h" +#include "SkStream.h" class SkColorTable; -class SkStream; -class SkStreamRewindable; // Empty implementations for SkImageDecoder. @@ -48,6 +47,13 @@ bool SkImageDecoder::buildTileIndex(SkStreamRewindable*, int *width, int *height return false; } +bool SkImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, + int* /*width*/, int* /*height*/) { + SkDELETE(stream); + return false; +} + + bool SkImageDecoder::decodeSubset(SkBitmap*, const SkIRect&, SkColorType) { return false; } diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp index 563a515..b777806 100644 --- a/src/ports/SkTypeface_win_dw.cpp +++ b/src/ports/SkTypeface_win_dw.cpp @@ -186,7 +186,7 @@ int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { } int ttcIndex; - SkAutoTUnref stream(this->openStream(&ttcIndex)); + SkAutoTDelete stream(this->openStream(&ttcIndex)); return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0; } diff --git a/src/sfnt/SkOTUtils.h b/src/sfnt/SkOTUtils.h index 51781b4..691bd76 100644 --- a/src/sfnt/SkOTUtils.h +++ b/src/sfnt/SkOTUtils.h @@ -33,6 +33,8 @@ struct SkOTUtils { * UnicodeBMPUCS2, and English_UnitedStates settings. * * fontName and fontNameLen must be specified in terms of ASCII chars. + * + * Does not affect fontData's ownership. */ static SkData* RenameFont(SkStream* fontData, const char* fontName, int fontNameLen); diff --git a/src/utils/SkFrontBufferedStream.cpp b/src/utils/SkFrontBufferedStream.cpp index ad5ae6e..562d376 100644 --- a/src/utils/SkFrontBufferedStream.cpp +++ b/src/utils/SkFrontBufferedStream.cpp @@ -31,7 +31,7 @@ public: SkStreamRewindable* duplicate() const SK_OVERRIDE { return NULL; } private: - SkAutoTUnref fStream; + SkAutoTDelete fStream; const bool fHasLength; const size_t fLength; // Current offset into the stream. Always >= 0. @@ -71,7 +71,7 @@ SkStreamRewindable* SkFrontBufferedStream::Create(SkStream* stream, size_t buffe } FrontBufferedStream::FrontBufferedStream(SkStream* stream, size_t bufferSize) - : fStream(SkRef(stream)) + : fStream(stream) , fHasLength(stream->hasPosition() && stream->hasLength()) , fLength(stream->getLength() - stream->getPosition()) , fOffset(0) diff --git a/src/utils/SkPDFRasterizer.cpp b/src/utils/SkPDFRasterizer.cpp index 1cb792f..d44dfa3 100644 --- a/src/utils/SkPDFRasterizer.cpp +++ b/src/utils/SkPDFRasterizer.cpp @@ -27,6 +27,7 @@ #ifdef SK_BUILD_POPPLER bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output) { + SkAutoTDelete streamDeleter(pdf); size_t size = pdf->getLength(); SkAutoFree buffer(sk_malloc_throw(size)); pdf->read(buffer.get(), size); @@ -81,6 +82,7 @@ bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output) { #ifdef SK_BUILD_NATIVE_PDF_RENDERER bool SkNativeRasterizePDF(SkStream* pdf, SkBitmap* output) { + SkAutoTDelete streamDeleter(pdf); return SkPDFNativeRenderToBitmap(pdf, output); } #endif // SK_BUILD_NATIVE_PDF_RENDERER diff --git a/src/utils/SkPDFRasterizer.h b/src/utils/SkPDFRasterizer.h index 82ec092..36bd086 100644 --- a/src/utils/SkPDFRasterizer.h +++ b/src/utils/SkPDFRasterizer.h @@ -11,10 +11,12 @@ #include "SkStream.h" #ifdef SK_BUILD_POPPLER +// Deletes pdf when finished. bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output); #endif // SK_BUILD_POPPLER #ifdef SK_BUILD_NATIVE_PDF_RENDERER +// Deletes pdf when finished. bool SkNativeRasterizePDF(SkStream* pdf, SkBitmap* output); #endif // SK_BUILD_NATIVE_PDF_RENDERER diff --git a/src/utils/mac/SkStream_mac.cpp b/src/utils/mac/SkStream_mac.cpp index 64d2dbb..2688471 100644 --- a/src/utils/mac/SkStream_mac.cpp +++ b/src/utils/mac/SkStream_mac.cpp @@ -8,13 +8,21 @@ #include "SkCGUtils.h" #include "SkStream.h" -// This is used by CGDataProviderCreateWithData +// These are used by CGDataProviderCreateWithData static void unref_proc(void* info, const void* addr, size_t size) { SkASSERT(info); ((SkRefCnt*)info)->unref(); } +static void delete_stream_proc(void* info, const void* addr, size_t size) { + SkASSERT(info); + SkStream* stream = (SkStream*)info; + SkASSERT(stream->getMemoryBase() == addr); + SkASSERT(stream->getLength() == size); + SkDELETE(stream); +} + // These are used by CGDataProviderSequentialCallbacks static size_t get_bytes_proc(void* info, void* buffer, size_t bytes) { @@ -31,19 +39,20 @@ static void rewind_proc(void* info) { ((SkStream*)info)->rewind(); } +// Used when info is an SkStream. static void release_info_proc(void* info) { SkASSERT(info); - ((SkStream*)info)->unref(); + SkDELETE((SkStream*)info); } CGDataProviderRef SkCreateDataProviderFromStream(SkStream* stream) { - stream->ref(); // unref will be called when the provider is deleted - + // TODO: Replace with SkStream::getData() when that is added. Then we only + // have one version of CGDataProviderCreateWithData (i.e. same release proc) const void* addr = stream->getMemoryBase(); if (addr) { // special-case when the stream is just a block of ram return CGDataProviderCreateWithData(stream, addr, stream->getLength(), - unref_proc); + delete_stream_proc); } CGDataProviderSequentialCallbacks rec; diff --git a/src/utils/win/SkDWriteFontFileStream.cpp b/src/utils/win/SkDWriteFontFileStream.cpp index 0f0c628..5569db5 100644 --- a/src/utils/win/SkDWriteFontFileStream.cpp +++ b/src/utils/win/SkDWriteFontFileStream.cpp @@ -142,7 +142,7 @@ HRESULT SkDWriteFontFileStreamWrapper::Create(SkStream* stream, SkDWriteFontFile } SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream) - : fRefCount(1), fStream(SkRef(stream)) { + : fRefCount(1), fStream(stream) { } HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID iid, void** ppvObject) { diff --git a/src/utils/win/SkDWriteFontFileStream.h b/src/utils/win/SkDWriteFontFileStream.h index 1800e2f..a7e4125 100644 --- a/src/utils/win/SkDWriteFontFileStream.h +++ b/src/utils/win/SkDWriteFontFileStream.h @@ -71,7 +71,7 @@ private: virtual ~SkDWriteFontFileStreamWrapper() { } ULONG fRefCount; - SkAutoTUnref fStream; + SkAutoTDelete fStream; SkMutex fStreamMutex; }; #endif diff --git a/src/views/animated/SkWidgetViews.cpp b/src/views/animated/SkWidgetViews.cpp index 8e7f517..cd22678 100644 --- a/src/views/animated/SkWidgetViews.cpp +++ b/src/views/animated/SkWidgetViews.cpp @@ -42,7 +42,7 @@ const char* get_skin_enum_path(SkinEnum se) void init_skin_anim(const char path[], SkAnimator* anim) { SkASSERT(path && anim); - SkAutoTUnref stream(SkStream::NewFromFile(path)); + SkAutoTDelete stream(SkStream::NewFromFile(path)); if (!stream.get()) { SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path)); sk_throw(); diff --git a/tests/FontHostStreamTest.cpp b/tests/FontHostStreamTest.cpp index 18c7460..affda98 100644 --- a/tests/FontHostStreamTest.cpp +++ b/tests/FontHostStreamTest.cpp @@ -96,8 +96,8 @@ DEF_TEST(FontHostStream, reporter) { } int ttcIndex; - SkAutoTUnref fontData(origTypeface->openStream(&ttcIndex)); - SkTypeface* streamTypeface = SkTypeface::CreateFromStream(fontData); + SkAutoTDelete fontData(origTypeface->openStream(&ttcIndex)); + SkTypeface* streamTypeface = SkTypeface::CreateFromStream(fontData.detach()); SkFontDescriptor desc; bool isLocalStream = false; diff --git a/tests/FrontBufferedStreamTest.cpp b/tests/FrontBufferedStreamTest.cpp index 167d1a2..69dade0 100644 --- a/tests/FrontBufferedStreamTest.cpp +++ b/tests/FrontBufferedStreamTest.cpp @@ -51,10 +51,13 @@ const char gAbcs[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef // Tests reading the stream across boundaries of what has been buffered so far and what // the total buffer size is. static void test_incremental_buffering(skiatest::Reporter* reporter, size_t bufferSize) { - SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); + // NOTE: For this and other tests in this file, we cheat and continue to refer to the + // wrapped stream, but that's okay because we know the wrapping stream has not been + // deleted yet (and we only call const methods in it). + SkMemoryStream* memStream = SkNEW_ARGS(SkMemoryStream, (gAbcs, strlen(gAbcs), false)); - SkAutoTUnref bufferedStream(SkFrontBufferedStream::Create(&memStream, bufferSize)); - test_hasLength(reporter, *bufferedStream.get(), memStream); + SkAutoTDelete bufferedStream(SkFrontBufferedStream::Create(memStream, bufferSize)); + test_hasLength(reporter, *bufferedStream.get(), *memStream); // First, test reading less than the max buffer size. test_read(reporter, bufferedStream, gAbcs, bufferSize / 2); @@ -79,9 +82,9 @@ static void test_incremental_buffering(skiatest::Reporter* reporter, size_t buff } static void test_perfectly_sized_buffer(skiatest::Reporter* reporter, size_t bufferSize) { - SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); - SkAutoTUnref bufferedStream(SkFrontBufferedStream::Create(&memStream, bufferSize)); - test_hasLength(reporter, *bufferedStream.get(), memStream); + SkMemoryStream* memStream = SkNEW_ARGS(SkMemoryStream, (gAbcs, strlen(gAbcs), false)); + SkAutoTDelete bufferedStream(SkFrontBufferedStream::Create(memStream, bufferSize)); + test_hasLength(reporter, *bufferedStream.get(), *memStream); // Read exactly the amount that fits in the buffer. test_read(reporter, bufferedStream, gAbcs, bufferSize); @@ -98,9 +101,9 @@ static void test_perfectly_sized_buffer(skiatest::Reporter* reporter, size_t buf } static void test_skipping(skiatest::Reporter* reporter, size_t bufferSize) { - SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); - SkAutoTUnref bufferedStream(SkFrontBufferedStream::Create(&memStream, bufferSize)); - test_hasLength(reporter, *bufferedStream.get(), memStream); + SkMemoryStream* memStream = SkNEW_ARGS(SkMemoryStream, (gAbcs, strlen(gAbcs), false)); + SkAutoTDelete bufferedStream(SkFrontBufferedStream::Create(memStream, bufferSize)); + test_hasLength(reporter, *bufferedStream.get(), *memStream); // Skip half the buffer. bufferedStream->skip(bufferSize / 2); @@ -149,11 +152,11 @@ private: // does not invalidate the buffer. static void test_read_beyond_buffer(skiatest::Reporter* reporter, size_t bufferSize) { // Use a stream that behaves like Android's stream. - AndroidLikeMemoryStream memStream((void*)gAbcs, bufferSize, false); + AndroidLikeMemoryStream* memStream = SkNEW_ARGS(AndroidLikeMemoryStream, ((void*)gAbcs, bufferSize, false)); // Create a buffer that matches the length of the stream. - SkAutoTUnref bufferedStream(SkFrontBufferedStream::Create(&memStream, bufferSize)); - test_hasLength(reporter, *bufferedStream.get(), memStream); + SkAutoTDelete bufferedStream(SkFrontBufferedStream::Create(memStream, bufferSize)); + test_hasLength(reporter, *bufferedStream.get(), *memStream); // Attempt to read one more than the bufferSize test_read(reporter, bufferedStream.get(), gAbcs, bufferSize + 1); @@ -197,22 +200,22 @@ private: static void test_length_combos(skiatest::Reporter* reporter, size_t bufferSize) { for (int hasLen = 0; hasLen <= 1; hasLen++) { for (int hasPos = 0; hasPos <= 1; hasPos++) { - LengthOptionalStream stream(SkToBool(hasLen), SkToBool(hasPos)); - SkAutoTUnref buffered(SkFrontBufferedStream::Create(&stream, bufferSize)); - test_hasLength(reporter, *buffered.get(), stream); + LengthOptionalStream* stream = SkNEW_ARGS(LengthOptionalStream, (SkToBool(hasLen), SkToBool(hasPos))); + SkAutoTDelete buffered(SkFrontBufferedStream::Create(stream, bufferSize)); + test_hasLength(reporter, *buffered.get(), *stream); } } } // Test using a stream with an initial offset. static void test_initial_offset(skiatest::Reporter* reporter, size_t bufferSize) { - SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); + SkMemoryStream* memStream = SkNEW_ARGS(SkMemoryStream, (gAbcs, strlen(gAbcs), false)); // Skip a few characters into the memStream, so that bufferedStream represents an offset into // the stream it wraps. const size_t arbitraryOffset = 17; - memStream.skip(arbitraryOffset); - SkAutoTUnref bufferedStream(SkFrontBufferedStream::Create(&memStream, bufferSize)); + memStream->skip(arbitraryOffset); + SkAutoTDelete bufferedStream(SkFrontBufferedStream::Create(memStream, bufferSize)); // Since SkMemoryStream has a length and a position, bufferedStream must also. REPORTER_ASSERT(reporter, bufferedStream->hasLength()); @@ -283,13 +286,13 @@ private: }; DEF_TEST(ShortFrontBufferedStream, reporter) { - FailingStream failingStream; - SkAutoTUnref stream(SkFrontBufferedStream::Create(&failingStream, 64)); + FailingStream* failingStream = SkNEW(FailingStream); + SkAutoTDelete stream(SkFrontBufferedStream::Create(failingStream, 64)); SkBitmap bm; // The return value of DecodeStream is not important. We are just using DecodeStream because // it simulates a bug. DecodeStream will read the stream, then rewind, then attempt to read // again. FrontBufferedStream::read should not continue to read its underlying stream beyond // its end. SkImageDecoder::DecodeStream(stream, &bm); - REPORTER_ASSERT(reporter, !failingStream.readAfterEnd()); + REPORTER_ASSERT(reporter, !failingStream->readAfterEnd()); } diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp index 78d6b6c..b94e29c 100644 --- a/tests/ImageDecodingTest.cpp +++ b/tests/ImageDecodingTest.cpp @@ -324,76 +324,13 @@ DEF_TEST(ImageDecoding_unpremul, reporter) { #endif // SK_BUILD_FOR_UNIX/ANDROID skbug.com/2388 #ifdef SK_DEBUG -// Create a stream containing a bitmap encoded to Type type. -static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) { - SkBitmap bm; - const int size = 50; - bm.allocN32Pixels(size, size); - SkCanvas canvas(bm); - SkPoint points[2] = { - { SkIntToScalar(0), SkIntToScalar(0) }, - { SkIntToScalar(size), SkIntToScalar(size) } - }; - SkColor colors[2] = { SK_ColorWHITE, SK_ColorBLUE }; - SkShader* shader = SkGradientShader::CreateLinear(points, colors, NULL, - SK_ARRAY_COUNT(colors), - SkShader::kClamp_TileMode); - SkPaint paint; - paint.setShader(shader)->unref(); - canvas.drawPaint(paint); - // Now encode it to a stream. - SkAutoTUnref data(SkImageEncoder::EncodeData(bm, type, 100)); - if (NULL == data.get()) { - return NULL; - } - return SkNEW_ARGS(SkMemoryStream, (data.get())); -} - -// For every format that supports tile based decoding, ensure that -// calling decodeSubset will not fail if the caller has unreffed the -// stream provided in buildTileIndex. -// Only runs in debug mode since we are testing for a crash. -static void test_stream_life() { - const SkImageEncoder::Type gTypes[] = { -#ifdef SK_BUILD_FOR_ANDROID - SkImageEncoder::kJPEG_Type, - SkImageEncoder::kPNG_Type, -#endif - SkImageEncoder::kWEBP_Type, - }; - for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) { - // SkDebugf("encoding to %i\n", i); - SkAutoTUnref stream(create_image_stream(gTypes[i])); - if (NULL == stream.get()) { - SkDebugf("no stream\n"); - continue; - } - SkAutoTDelete decoder(SkImageDecoder::Factory(stream)); - if (NULL == decoder.get()) { - SkDebugf("no decoder\n"); - continue; - } - int width, height; - if (!decoder->buildTileIndex(stream.get(), &width, &height)) { - SkDebugf("could not build a tile index\n"); - continue; - } - // Now unref the stream to make sure it survives - stream.reset(NULL); - SkBitmap bm; - decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height), kN32_SkColorType); - } -} - // Test inside SkScaledBitmapSampler.cpp extern void test_row_proc_choice(); - #endif // SK_DEBUG DEF_TEST(ImageDecoding, reporter) { test_unpremul(reporter); #ifdef SK_DEBUG - test_stream_life(); test_row_proc_choice(); #endif } @@ -488,7 +425,6 @@ static SkPixelRef* install_pixel_ref(SkBitmap* bitmap, SkASSERT(bitmap != NULL); SkASSERT(stream != NULL); SkASSERT(stream->rewind()); - SkASSERT(stream->unique()); SkColorType colorType = bitmap->colorType(); SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType); if (SkInstallDiscardablePixelRef( @@ -503,7 +439,7 @@ static SkPixelRef* install_pixel_ref(SkBitmap* bitmap, */ DEF_TEST(ImprovedBitmapFactory, reporter) { SkString pngFilename = GetResourcePath("randPixels.png"); - SkAutoTUnref stream(SkStream::NewFromFile(pngFilename.c_str())); + SkAutoTDelete stream(SkStream::NewFromFile(pngFilename.c_str())); if (sk_exists(pngFilename.c_str())) { SkBitmap bm; SkAssertResult(bm.setInfo(SkImageInfo::MakeN32Premul(1, 1))); @@ -698,7 +634,7 @@ DEF_TEST(ImageDecoderOptions, reporter) { SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str())); REPORTER_ASSERT(reporter, encodedData.get() != NULL); - SkAutoTUnref encodedStream( + SkAutoTDelete encodedStream( SkStream::NewFromFile(path.c_str())); REPORTER_ASSERT(reporter, encodedStream.get() != NULL); @@ -782,7 +718,7 @@ private: DEF_TEST(ImageDecoding_JpegOverwrite, r) { SkString resourceDir = GetResourcePath(); SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg"); - SkAutoTUnref stream( + SkAutoTDelete stream( SkStream::NewFromFile(path.c_str())); if (!stream.get()) { SkDebugf("\nPath '%s' missing.\n", path.c_str()); diff --git a/tests/KtxTest.cpp b/tests/KtxTest.cpp index 23c1d70..53caabd 100644 --- a/tests/KtxTest.cpp +++ b/tests/KtxTest.cpp @@ -55,7 +55,7 @@ DEF_TEST(KtxReadWrite, reporter) { SkAutoDataUnref encodedData(SkImageEncoder::EncodeData(bm8888, SkImageEncoder::kKTX_Type, 0)); REPORTER_ASSERT(reporter, encodedData); - SkAutoTUnref stream(SkNEW_ARGS(SkMemoryStream, (encodedData))); + SkAutoTDelete stream(SkNEW_ARGS(SkMemoryStream, (encodedData))); REPORTER_ASSERT(reporter, stream); SkBitmap decodedBitmap; @@ -107,7 +107,7 @@ DEF_TEST(KtxReadUnpremul, reporter) { 0xFF, 0xFF, 0xFF, 0x80, // Pixel 3 0xFF, 0xFF, 0xFF, 0x80};// Pixel 4 - SkAutoTUnref stream( + SkAutoTDelete stream( SkNEW_ARGS(SkMemoryStream, (kHalfWhiteKTX, sizeof(kHalfWhiteKTX)))); REPORTER_ASSERT(reporter, stream); diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp index 3a4c6f6..3610dd9 100644 --- a/tests/PDFPrimitivesTest.cpp +++ b/tests/PDFPrimitivesTest.cpp @@ -119,7 +119,7 @@ static void SimpleCheckObjectOutput(skiatest::Reporter* reporter, static void TestPDFStream(skiatest::Reporter* reporter) { char streamBytes[] = "Test\nFoo\tBar"; - SkAutoTUnref streamData(new SkMemoryStream( + SkAutoTDelete streamData(new SkMemoryStream( streamBytes, strlen(streamBytes), true)); SkAutoTUnref stream(new SkPDFStream(streamData.get())); SimpleCheckObjectOutput( diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp index cd5bc60..f6a8a7d 100644 --- a/tests/SerializationTest.cpp +++ b/tests/SerializationTest.cpp @@ -350,7 +350,7 @@ static void TestPictureTypefaceSerialization(skiatest::Reporter* reporter) { // Serlialize picture and create its clone from stream. SkDynamicMemoryWStream stream; picture->serialize(&stream); - SkAutoTUnref inputStream(stream.detachAsStream()); + SkAutoTDelete inputStream(stream.detachAsStream()); SkAutoTUnref loadedPicture(SkPicture::CreateFromStream(inputStream.get())); // Draw both original and clone picture and compare bitmaps -- they should be identical. diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp index ab0af14..ff22ecf 100644 --- a/tests/StreamTest.cpp +++ b/tests/StreamTest.cpp @@ -58,7 +58,7 @@ static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) { REPORTER_ASSERT(reporter, stream.isValid()); test_loop_stream(reporter, &stream, s, 26, 100); - SkAutoTUnref stream2(stream.duplicate()); + SkAutoTDelete stream2(stream.duplicate()); test_loop_stream(reporter, stream2.get(), s, 26, 100); } @@ -68,7 +68,7 @@ static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) { REPORTER_ASSERT(reporter, stream.isValid()); test_loop_stream(reporter, &stream, s, 26, 100); - SkAutoTUnref stream2(stream.duplicate()); + SkAutoTDelete stream2(stream.duplicate()); test_loop_stream(reporter, stream2.get(), s, 26, 100); } } @@ -91,15 +91,15 @@ static void TestWStream(skiatest::Reporter* reporter) { } { - SkAutoTUnref stream(ds.detachAsStream()); + SkAutoTDelete stream(ds.detachAsStream()); REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength()); REPORTER_ASSERT(reporter, ds.getOffset() == 0); test_loop_stream(reporter, stream.get(), s, 26, 100); - SkAutoTUnref stream2(stream->duplicate()); + SkAutoTDelete stream2(stream->duplicate()); test_loop_stream(reporter, stream2.get(), s, 26, 100); - SkAutoTUnref stream3(stream->fork()); + SkAutoTDelete stream3(stream->fork()); REPORTER_ASSERT(reporter, stream3->isAtEnd()); char tmp; size_t bytes = stream->read(&tmp, 1); @@ -121,11 +121,11 @@ static void TestWStream(skiatest::Reporter* reporter) { { // Test that this works after a copyToData. - SkAutoTUnref stream(ds.detachAsStream()); + SkAutoTDelete stream(ds.detachAsStream()); REPORTER_ASSERT(reporter, ds.getOffset() == 0); test_loop_stream(reporter, stream.get(), s, 26, 100); - SkAutoTUnref stream2(stream->duplicate()); + SkAutoTDelete stream2(stream->duplicate()); test_loop_stream(reporter, stream2.get(), s, 26, 100); } delete[] dst; diff --git a/tools/dump_record.cpp b/tools/dump_record.cpp index fc2e102..885046a 100644 --- a/tools/dump_record.cpp +++ b/tools/dump_record.cpp @@ -46,7 +46,7 @@ int tool_main(int argc, char** argv) { continue; } - SkAutoTUnref stream(SkStream::NewFromFile(FLAGS_skps[i])); + SkAutoTDelete stream(SkStream::NewFromFile(FLAGS_skps[i])); if (!stream) { SkDebugf("Could not read %s.\n", FLAGS_skps[i]); exit(1); diff --git a/tools/lua/lua_pictures.cpp b/tools/lua/lua_pictures.cpp index 6c7087f..d579f2e 100644 --- a/tools/lua/lua_pictures.cpp +++ b/tools/lua/lua_pictures.cpp @@ -39,7 +39,7 @@ DEFINE_string2(tailFunc, s, "", "Optional lua function to call at end"); DEFINE_bool2(quiet, q, false, "Silence all non-error related output"); static SkPicture* load_picture(const char path[]) { - SkAutoTUnref stream(SkStream::NewFromFile(path)); + SkAutoTDelete stream(SkStream::NewFromFile(path)); SkPicture* pic = NULL; if (stream.get()) { pic = SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap);