diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-18 21:08:46 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-18 21:08:46 +0000 |
commit | e1575aa21619e252f6c6514317041c32d00ce5a6 (patch) | |
tree | 2b2bcf4bd1ea896e7da510cae04ef0b3b2ef9ef7 | |
parent | 070235e746c46f6c0a26ed6c23c832c532b974e9 (diff) |
reland 8200 w/ fix for android (use fullpath instead of path)
Review URL: https://codereview.chromium.org/12921003
git-svn-id: http://skia.googlecode.com/svn/trunk@8206 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gyp/core.gyp | 4 | ||||
-rw-r--r-- | gyp/core.gypi | 1 | ||||
-rw-r--r-- | include/core/SkData.h | 6 | ||||
-rw-r--r-- | include/core/SkMMapStream.h | 30 | ||||
-rw-r--r-- | include/core/SkPreConfig.h | 11 | ||||
-rw-r--r-- | include/core/SkStream.h | 7 | ||||
-rw-r--r-- | src/core/SkData.cpp | 22 | ||||
-rw-r--r-- | src/core/SkMMapStream.cpp | 77 | ||||
-rw-r--r-- | src/core/SkStream.cpp | 64 | ||||
-rw-r--r-- | src/ports/SkFontHost_android.cpp | 51 | ||||
-rw-r--r-- | src/ports/SkFontHost_ascender.cpp | 2 | ||||
-rw-r--r-- | src/ports/SkFontHost_freetype_mac.cpp | 7 | ||||
-rw-r--r-- | src/ports/SkFontHost_linux.cpp | 49 | ||||
-rw-r--r-- | src/ports/SkFontHost_simple.cpp | 48 |
14 files changed, 156 insertions, 223 deletions
diff --git a/gyp/core.gyp b/gyp/core.gyp index 57f31ba566..5f99fd911e 100644 --- a/gyp/core.gyp +++ b/gyp/core.gyp @@ -74,10 +74,6 @@ 'include_dirs': [ 'config/win', ], - 'sources!': [ - '../include/core/SkMMapStream.h', - '../src/core/SkMMapStream.cpp', - ], }], [ 'skia_os in ("android", "nacl")', { 'dependencies': [ diff --git a/gyp/core.gypi b/gyp/core.gypi index 3c2be39c05..23a652acb8 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -105,7 +105,6 @@ '<(skia_src_path)/core/SkMath.cpp', '<(skia_src_path)/core/SkMatrix.cpp', '<(skia_src_path)/core/SkMetaData.cpp', - '<(skia_src_path)/core/SkMMapStream.cpp', '<(skia_src_path)/core/SkOrderedReadBuffer.cpp', '<(skia_src_path)/core/SkOrderedWriteBuffer.cpp', '<(skia_src_path)/core/SkPackBits.cpp', diff --git a/include/core/SkData.h b/include/core/SkData.h index 9a0cb09b60..6b09119fc5 100644 --- a/include/core/SkData.h +++ b/include/core/SkData.h @@ -89,6 +89,12 @@ public: static SkData* NewFromMalloc(const void* data, size_t length); /** + * Create a new dataref from a pointer allocated by mmap. The Data object + * will handle calling munmap(). + */ + static SkData* NewFromMMap(const void* data, size_t length); + + /** * Create a new dataref using a subset of the data in the specified * src dataref. */ diff --git a/include/core/SkMMapStream.h b/include/core/SkMMapStream.h deleted file mode 100644 index a3b35f2df8..0000000000 --- a/include/core/SkMMapStream.h +++ /dev/null @@ -1,30 +0,0 @@ - -/* - * Copyright 2008 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkMMapStream_DEFINED -#define SkMMapStream_DEFINED - -#include "SkStream.h" - -class SkMMAPStream : public SkMemoryStream { -public: - SkMMAPStream(const char filename[]); - virtual ~SkMMAPStream(); - - virtual void setMemory(const void* data, size_t length, bool); -private: - void* fAddr; - size_t fSize; - - void closeMMap(); - - typedef SkMemoryStream INHERITED; -}; - -#endif diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h index 2246b63f59..11cb2235a7 100644 --- a/include/core/SkPreConfig.h +++ b/include/core/SkPreConfig.h @@ -108,6 +108,17 @@ ////////////////////////////////////////////////////////////////////// +#ifndef SK_MMAP_SUPPORT + #ifdef SK_BUILD_FOR_WIN32 + // by default, if we're windows, we assume we don't have mmap + #define SK_MMAP_SUPPORT 0 + #else + #define SK_MMAP_SUPPORT 1 + #endif +#endif + +////////////////////////////////////////////////////////////////////// + /** * SK_CPU_SSE_LEVEL * diff --git a/include/core/SkStream.h b/include/core/SkStream.h index 7e3c1a370b..eb0cd4757f 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -17,6 +17,13 @@ class SkData; class SK_API SkStream : public SkRefCnt { public: + /** + * 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. + */ + static SkStream* NewFromFile(const char path[]); + SK_DECLARE_INST_COUNT(SkStream) /** Called to rewind to the beginning of the stream. If this cannot be diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp index 3e0c71a0e8..8fbca7af5f 100644 --- a/src/core/SkData.cpp +++ b/src/core/SkData.cpp @@ -8,6 +8,13 @@ #include "SkData.h" #include "SkFlattenableBuffers.h" +#if SK_MMAP_SUPPORT + #include <unistd.h> + #include <sys/mman.h> + #include <fcntl.h> + #include <errno.h> +#endif + SK_DEFINE_INST_COUNT(SkData) SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { @@ -120,6 +127,20 @@ SkData* SkData::NewWithCString(const char cstr[]) { return NewWithCopy(cstr, size); } +#if SK_MMAP_SUPPORT +static void sk_munmap_releaseproc(const void* addr, size_t length, void*) { + munmap(const_cast<void*>(addr), length); +} + +SkData* SkData::NewFromMMap(const void* addr, size_t length) { + return SkNEW_ARGS(SkData, (addr, length, sk_munmap_releaseproc, NULL)); +} +#else +SkData* SkData::NewFromMMap(const void* addr, size_t length) { + return NULL; +} +#endif + /////////////////////////////////////////////////////////////////////////////// void SkData::flatten(SkFlattenableWriteBuffer& buffer) const { @@ -300,3 +321,4 @@ SkDataSet* SkDataSet::NewEmpty() { gEmptySet->ref(); return gEmptySet; } + diff --git a/src/core/SkMMapStream.cpp b/src/core/SkMMapStream.cpp deleted file mode 100644 index 7388e81498..0000000000 --- a/src/core/SkMMapStream.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "SkMMapStream.h" - -#include <unistd.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <errno.h> - -SkMMAPStream::SkMMAPStream(const char filename[]) -{ - fAddr = NULL; // initialize to failure case - fSize = 0; - - int fildes = open(filename, O_RDONLY); - if (fildes < 0) - { - SkDEBUGF(("---- failed to open(%s) for mmap stream error=%d\n", filename, errno)); - return; - } - - off_t offset = lseek(fildes, 0, SEEK_END); // find the file size - if (offset == -1) - { - SkDEBUGF(("---- failed to lseek(%s) for mmap stream error=%d\n", filename, errno)); - close(fildes); - return; - } - (void)lseek(fildes, 0, SEEK_SET); // restore file offset to beginning - - // to avoid a 64bit->32bit warning, I explicitly create a size_t size - size_t size = static_cast<size_t>(offset); - - void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fildes, 0); - - // According to the POSIX documentation of mmap it adds an extra reference - // to the file associated with the fildes which is not removed by a - // subsequent close() on that fildes. This reference is removed when there - // are no more mappings to the file. - close(fildes); - - if (MAP_FAILED == addr) - { - SkDEBUGF(("---- failed to mmap(%s) for mmap stream error=%d\n", filename, errno)); - return; - } - - this->INHERITED::setMemory(addr, size); - - fAddr = addr; - fSize = size; -} - -SkMMAPStream::~SkMMAPStream() -{ - this->closeMMap(); -} - -void SkMMAPStream::setMemory(const void* data, size_t length, bool copyData) -{ - this->closeMMap(); - this->INHERITED::setMemory(data, length, copyData); -} - -void SkMMAPStream::closeMMap() -{ - if (fAddr) - { - munmap(fAddr, fSize); - fAddr = NULL; - } -} diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp index fb343ea76a..acbcfbc53d 100644 --- a/src/core/SkStream.cpp +++ b/src/core/SkStream.cpp @@ -13,6 +13,14 @@ #include "SkString.h" #include "SkOSFile.h" +#if SK_MMAP_SUPPORT + #include <unistd.h> + #include <sys/mman.h> + #include <fcntl.h> + #include <errno.h> + #include <unistd.h> +#endif + SK_DEFINE_INST_COUNT(SkStream) SK_DEFINE_INST_COUNT(SkWStream) SK_DEFINE_INST_COUNT(SkFILEStream) @@ -789,3 +797,59 @@ bool SkDebugWStream::write(const void* buffer, size_t size) #endif return true; } + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +static bool mmap_filename(const char path[], void** addrPtr, size_t* sizePtr) { +#if SK_MMAP_SUPPORT + int fd = open(path, O_RDONLY); + if (fd < 0) { + return false; + } + + off_t offset = lseek(fd, 0, SEEK_END); // find the file size + if (offset == -1) { + close(fd); + return false; + } + (void)lseek(fd, 0, SEEK_SET); // restore file offset to beginning + + // to avoid a 64bit->32bit warning, I explicitly create a size_t size + size_t size = static_cast<size_t>(offset); + + void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + + if (MAP_FAILED == addr) { + return false; + } + + *addrPtr = addr; + *sizePtr = size; + return true; +#else + return false; +#endif +} + +SkStream* SkStream::NewFromFile(const char path[]) { + void* addr; + size_t size; + if (mmap_filename(path, &addr, &size)) { + SkAutoTUnref<SkData> data(SkData::NewFromMMap(addr, size)); + if (data.get()) { + return SkNEW_ARGS(SkMemoryStream, (data.get())); + } + } + + // If we get here, then our attempt at using mmap failed, so try normal + // file access. + SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); + if (!stream->isValid()) { + stream->unref(); + stream = NULL; + } + return stream; +} + diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp index e1d6cf471e..a955b6313b 100644 --- a/src/ports/SkFontHost_android.cpp +++ b/src/ports/SkFontHost_android.cpp @@ -9,7 +9,6 @@ #include "SkFontDescriptor.h" #include "SkGraphics.h" #include "SkDescriptor.h" -#include "SkMMapStream.h" #include "SkPaint.h" #include "SkString.h" #include "SkStream.h" @@ -370,30 +369,19 @@ public: fPath.set(path); } - // overrides - virtual SkStream* openStream() { - SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); - - // check for failure - if (stream->getLength() <= 0) { - SkDELETE(stream); - // maybe MMAP isn't supported. try FILE - stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); - if (stream->getLength() <= 0) { - SkDELETE(stream); - stream = NULL; - } - } - return stream; + virtual SkStream* openStream() SK_OVERRIDE { + return SkStream::NewFromFile(fPath.c_str()); } - virtual const char* getUniqueString() const { + + virtual const char* getUniqueString() const SK_OVERRIDE { const char* str = strrchr(fPath.c_str(), '/'); if (str) { str += 1; // skip the '/' } return str; } - virtual const char* getFilePath() const { + + virtual const char* getFilePath() const SK_OVERRIDE { return fPath.c_str(); } @@ -412,21 +400,15 @@ static bool get_name_and_style(const char path[], SkString* name, SkString fullpath; GetFullPathForSysFonts(&fullpath, path); - SkMMAPStream stream(fullpath.c_str()); - if (stream.getLength() > 0) { - return find_name_and_attributes(&stream, name, style, isFixedWidth); - } - else { - SkFILEStream stream(fullpath.c_str()); - if (stream.getLength() > 0) { - return find_name_and_attributes(&stream, name, style, isFixedWidth); + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(fullpath.c_str())); + if (stream.get()) { + return find_name_and_attributes(stream, name, style, isFixedWidth); + } else { + if (isExpected) { + SkDebugf("---- failed to open <%s> as a font", fullpath.c_str()); } + return false; } - - if (isExpected) { - SkDebugf("---- failed to open <%s> as a font", fullpath.c_str()); - } - return false; } // used to record our notion of the pre-existing fonts @@ -952,11 +934,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { } SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { - SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); - SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); - // since we created the stream, we let go of our ref() here - stream->unref(); - return face; + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); + return stream.get() ? SkFontHost::CreateTypefaceFromStream(stream) : NULL; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/ports/SkFontHost_ascender.cpp b/src/ports/SkFontHost_ascender.cpp index d20cc825cd..51210d9642 100644 --- a/src/ports/SkFontHost_ascender.cpp +++ b/src/ports/SkFontHost_ascender.cpp @@ -21,8 +21,6 @@ ////////////////////////////////////////////////////////////////////////// -#include "SkMMapStream.h" - class SkScalerContext_Ascender : public SkScalerContext { public: SkScalerContext_Ascender(const SkDescriptor* desc); diff --git a/src/ports/SkFontHost_freetype_mac.cpp b/src/ports/SkFontHost_freetype_mac.cpp index bc197d6872..3d89bc613a 100644 --- a/src/ports/SkFontHost_freetype_mac.cpp +++ b/src/ports/SkFontHost_freetype_mac.cpp @@ -6,7 +6,6 @@ */ #include "SkFontHost.h" -#include "SkMMapStream.h" #include "SkTypefaceCache.h" #define FONT_PATH "/Library/Fonts/Skia.ttf" @@ -26,7 +25,11 @@ public: }; static FTMacTypeface* create_from_path(const char path[]) { - SkStream* stream = new SkMMAPStream(path); + SkStream* stream = SkStream::NewFromFile(path); + if (!stream) { + return NULL; + } + size_t size = stream->getLength(); SkASSERT(size); FTMacTypeface* tf = new FTMacTypeface(SkTypeface::kNormal, diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp index 07235c875f..25ae7effe2 100644 --- a/src/ports/SkFontHost_linux.cpp +++ b/src/ports/SkFontHost_linux.cpp @@ -10,7 +10,6 @@ #include "SkFontHost.h" #include "SkFontDescriptor.h" #include "SkDescriptor.h" -#include "SkMMapStream.h" #include "SkOSFile.h" #include "SkPaint.h" #include "SkString.h" @@ -280,8 +279,8 @@ public: EmptyTypeface() : INHERITED(SkTypeface::kNormal, true, NULL, false) {} // overrides - virtual SkStream* openStream() { return NULL; } - virtual const char* getUniqueString() const { return NULL; } + virtual SkStream* openStream() SK_OVERRIDE { return NULL; } + virtual const char* getUniqueString() SK_OVERRIDE const { return NULL; } private: typedef FamilyTypeface INHERITED; @@ -299,14 +298,12 @@ public: fStream->unref(); } - // overrides - virtual SkStream* openStream() - { + virtual SkStream* openStream() SK_OVERRIDE { // openStream returns a refed stream. fStream->ref(); return fStream; } - virtual const char* getUniqueString() const { return NULL; } + virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; } private: SkStream* fStream; @@ -322,25 +319,11 @@ public: fPath.set(path); } - // overrides - virtual SkStream* openStream() - { - SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); - - // check for failure - if (stream->getLength() <= 0) { - SkDELETE(stream); - // maybe MMAP isn't supported. try FILE - stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); - if (stream->getLength() <= 0) { - SkDELETE(stream); - stream = NULL; - } - } - return stream; + virtual SkStream* openStream() SK_OVERRIDE { + return SkStream::NewFromFile(fPath.c_str()); } - virtual const char* getUniqueString() const { + virtual const char* getUniqueString() const SK_OVERRIDE { const char* str = strrchr(fPath.c_str(), '/'); if (str) { str += 1; // skip the '/' @@ -359,19 +342,13 @@ private: static bool get_name_and_style(const char path[], SkString* name, SkTypeface::Style* style, bool* isFixedWidth) { - SkMMAPStream stream(path); - if (stream.getLength() > 0) { - return find_name_and_attributes(&stream, name, style, isFixedWidth); - } - else { - SkFILEStream stream(path); - if (stream.getLength() > 0) { - return find_name_and_attributes(&stream, name, style, isFixedWidth); - } + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); + if (stream.get()) { + return find_name_and_attributes(stream, name, style, isFixedWidth); + } else { + SkDebugf("---- failed to open <%s> as a font\n", path); + return false; } - - SkDebugf("---- failed to open <%s> as a font\n", path); - return false; } // these globals are assigned (once) by load_system_fonts() diff --git a/src/ports/SkFontHost_simple.cpp b/src/ports/SkFontHost_simple.cpp index 101d5761d2..b4f6ce0f1d 100644 --- a/src/ports/SkFontHost_simple.cpp +++ b/src/ports/SkFontHost_simple.cpp @@ -9,7 +9,6 @@ #include "SkFontHost.h" #include "SkDescriptor.h" -#include "SkMMapStream.h" #include "SkPaint.h" #include "SkString.h" #include "SkStream.h" @@ -312,30 +311,18 @@ public: fPath.set(path); } - // overrides - virtual SkStream* openStream() { - SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); - - // check for failure - if (stream->getLength() <= 0) { - SkDELETE(stream); - // maybe MMAP isn't supported. try FILE - stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); - if (stream->getLength() <= 0) { - SkDELETE(stream); - stream = NULL; - } - } - return stream; + virtual SkStream* openStream() SK_OVERRIDE { + return SkStream::NewFromFile(fPath.c_str()); } - virtual const char* getUniqueString() const { + + virtual const char* getUniqueString() const SK_OVERRIDE { const char* str = strrchr(fPath.c_str(), '/'); if (str) { str += 1; // skip the '/' } return str; } - virtual const char* getFilePath() const { + virtual const char* getFilePath() const SK_OVERRIDE { return fPath.c_str(); } @@ -353,21 +340,15 @@ static bool get_name_and_style(const char path[], SkString* name, SkString fullpath; GetFullPathForSysFonts(&fullpath, path); - SkMMAPStream stream(fullpath.c_str()); - if (stream.getLength() > 0) { + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(fullpath.c_str())); + if (stream.get()) { return find_name_and_attributes(&stream, name, style, NULL); - } - else { - SkFILEStream stream(fullpath.c_str()); - if (stream.getLength() > 0) { - return find_name_and_attributes(&stream, name, style, NULL); + } else { + if (isExpected) { + SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str()); } + return false; } - - if (isExpected) { - SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str()); - } - return false; } // used to record our notion of the pre-existing fonts @@ -636,9 +617,6 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { } SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { - SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path)); - SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream); - // since we created the stream, we let go of our ref() here - stream->unref(); - return face; + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); + return stream.get() ? SkFontHost::CreateTypefaceFromStream(stream) : NULL; } |