зеркало из https://github.com/mozilla/moz-skia.git
Move MMap to SkData.
R=reed@google.com Author: bungeman@google.com Review URL: https://chromiumcodereview.appspot.com/14336003 git-svn-id: http://skia.googlecode.com/svn/trunk@8848 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
d0419019de
Коммит
9711e44667
|
@ -32,12 +32,12 @@ protected:
|
|||
// Copyright-free file from http://openclipart.org/detail/29213/paper-plane-by-ddoo
|
||||
filename.append("plane.png");
|
||||
|
||||
SkFILEStream stream(filename.c_str());
|
||||
if (stream.isValid()) {
|
||||
stream.rewind();
|
||||
size_t length = stream.getLength();
|
||||
SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(filename.c_str()));
|
||||
if (NULL != stream.get()) {
|
||||
stream->rewind();
|
||||
size_t length = stream->getLength();
|
||||
void* buffer = sk_malloc_throw(length);
|
||||
stream.read(buffer, length);
|
||||
stream->read(buffer, length);
|
||||
SkAutoDataUnref data(SkData::NewFromMalloc(buffer, length));
|
||||
SkBitmapFactory factory(&SkImageDecoder::DecodeMemoryToTarget);
|
||||
// Create a cache which will boot the pixels out anytime the
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
struct SkFILE;
|
||||
|
||||
/**
|
||||
* SkData holds an immutable data buffer. Not only is the data immutable,
|
||||
* but the actual ptr that is returned (by data() or bytes()) is guaranteed
|
||||
|
@ -89,10 +91,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().
|
||||
* Create a new dataref from a SkFILE.
|
||||
* This does not take ownership of the SkFILE, nor close it.
|
||||
* The SkFILE must be open for reading only.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static SkData* NewFromMMap(const void* data, size_t length);
|
||||
static SkData* NewFromFILE(SkFILE* f);
|
||||
|
||||
/**
|
||||
* Create a new dataref using a subset of the data in the specified
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
|
||||
#include "SkData.h"
|
||||
#include "SkFlattenableBuffers.h"
|
||||
#include "SkOSFile.h"
|
||||
|
||||
#if SK_MMAP_SUPPORT
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
SK_DEFINE_INST_COUNT(SkData)
|
||||
|
@ -94,6 +98,90 @@ static void sk_dataref_releaseproc(const void*, size_t, void* context) {
|
|||
src->unref();
|
||||
}
|
||||
|
||||
#if SK_MMAP_SUPPORT
|
||||
|
||||
static void sk_munmap_releaseproc(const void* addr, size_t length, void*) {
|
||||
munmap(const_cast<void*>(addr), length);
|
||||
}
|
||||
|
||||
SkData* SkData::NewFromFILE(SkFILE* f) {
|
||||
size_t size = sk_fgetsize(f);
|
||||
if (0 == size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fd = fileno((FILE*)f);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (MAP_FAILED == addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL);
|
||||
}
|
||||
|
||||
#elif SK_BUILD_FOR_WIN32
|
||||
|
||||
template <typename HandleType, HandleType InvalidValue, BOOL (WINAPI * Close)(HandleType)>
|
||||
class SkAutoTHandle : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTHandle(HandleType handle) : fHandle(handle) { }
|
||||
~SkAutoTHandle() { Close(fHandle); }
|
||||
operator HandleType() { return fHandle; }
|
||||
bool isValid() { return InvalidValue != fHandle; }
|
||||
private:
|
||||
HandleType fHandle;
|
||||
};
|
||||
typedef SkAutoTHandle<HANDLE, INVALID_HANDLE_VALUE, CloseHandle> SkAutoWinFile;
|
||||
typedef SkAutoTHandle<HANDLE, NULL, CloseHandle> SkAutoWinMMap;
|
||||
|
||||
static void sk_munmap_releaseproc(const void* addr, size_t, void*) {
|
||||
UnmapViewOfFile(addr);
|
||||
}
|
||||
|
||||
SkData* SkData::NewFromFILE(SkFILE* f) {
|
||||
size_t size = sk_fgetsize(f);
|
||||
if (0 == size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fileno = _fileno((FILE*)f);
|
||||
if (fileno < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE file = (HANDLE)_get_osfhandle(fileno);
|
||||
if (INVALID_HANDLE_VALUE == file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL));
|
||||
if (!mmap.isValid()) {
|
||||
//TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.") to report.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Eventually call UnmapViewOfFile
|
||||
void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0);
|
||||
if (NULL == addr) {
|
||||
//TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to report.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SkData* SkData::NewFromFILE(SkFILE* f) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) {
|
||||
/*
|
||||
We could, if we wanted/need to, just make a deep copy of src's data,
|
||||
|
@ -127,20 +215,6 @@ 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 {
|
||||
|
|
|
@ -13,14 +13,6 @@
|
|||
#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)
|
||||
|
@ -796,46 +788,22 @@ bool SkDebugWStream::write(const void* buffer, size_t size)
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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;
|
||||
|
||||
static SkData* mmap_filename(const char path[]) {
|
||||
SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
|
||||
if (NULL == file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
SkData* data = SkData::NewFromFILE(file);
|
||||
sk_fclose(file);
|
||||
return data;
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
SkAutoTUnref<SkData> data(mmap_filename(path));
|
||||
if (data.get()) {
|
||||
return SkNEW_ARGS(SkMemoryStream, (data.get()));
|
||||
}
|
||||
|
||||
// If we get here, then our attempt at using mmap failed, so try normal
|
||||
|
|
|
@ -33,6 +33,8 @@ SkFILE* sk_fopen(const char path[], SkFILE_Flags flags)
|
|||
*p++ = 'b';
|
||||
*p = 0;
|
||||
|
||||
//TODO: on Windows fopen is just ASCII or the current code page,
|
||||
//convert to utf16 and use _wfopen
|
||||
SkFILE* f = (SkFILE*)::fopen(path, perm);
|
||||
#if 0
|
||||
if (NULL == f)
|
||||
|
|
|
@ -29,7 +29,7 @@ void SkTraceHR(const char* file, unsigned long line,
|
|||
if (NULL == errorText) {
|
||||
SkDEBUGF(("<unknown>\n"));
|
||||
} else {
|
||||
SkDEBUGF((errorText));
|
||||
SkDEBUGF(("%s", errorText));
|
||||
LocalFree(errorText);
|
||||
errorText = NULL;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче