Linux: use mmap fonts.
FreeType makes a lot of seek calls when we give it fonts as a stream. To avoid the seeks (which hurt the SUID sandbox), we mmap the fonts. Will need to pay attention to the perf bots after this lands. http://codereview.chromium.org/180026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24790 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -27,8 +27,9 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "SkFontHost.h"
|
#include "SkFontHost.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
@ -235,17 +236,28 @@ uint32_t SkFontHost::NextLogicalFont(SkFontID fontID) {
|
|||||||
|
|
||||||
class SkFileDescriptorStream : public SkStream {
|
class SkFileDescriptorStream : public SkStream {
|
||||||
public:
|
public:
|
||||||
SkFileDescriptorStream(int fd)
|
SkFileDescriptorStream(int fd) {
|
||||||
: fd_(fd) {
|
memory_ = NULL;
|
||||||
|
offset_ = 0;
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st))
|
||||||
|
return;
|
||||||
|
|
||||||
|
void* memory = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (memory == MAP_FAILED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memory_ = reinterpret_cast<uint8_t*>(memory);
|
||||||
|
length_ = st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
~SkFileDescriptorStream() {
|
~SkFileDescriptorStream() {
|
||||||
close(fd_);
|
munmap(const_cast<uint8_t*>(memory_), length_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool rewind() {
|
virtual bool rewind() {
|
||||||
if (lseek(fd_, 0, SEEK_SET) == -1)
|
offset_ = 0;
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,33 +265,34 @@ class SkFileDescriptorStream : public SkStream {
|
|||||||
virtual size_t read(void* buffer, size_t size) {
|
virtual size_t read(void* buffer, size_t size) {
|
||||||
if (!buffer && !size) {
|
if (!buffer && !size) {
|
||||||
// This is request for the length of the stream.
|
// This is request for the length of the stream.
|
||||||
struct stat st;
|
return length_;
|
||||||
if (fstat(fd_, &st) == -1)
|
|
||||||
return 0;
|
|
||||||
return st.st_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
// This is a request to skip bytes.
|
// This is a request to skip bytes.
|
||||||
const off_t current_position = lseek(fd_, 0, SEEK_CUR);
|
if (offset_ + size < offset_)
|
||||||
if (current_position == -1)
|
return offset_;
|
||||||
return 0;
|
offset_ += size;
|
||||||
const off_t new_position = lseek(fd_, size, SEEK_CUR);
|
if (offset_ > length_)
|
||||||
if (new_position == -1)
|
offset_ = length_;
|
||||||
return 0;
|
return offset_;
|
||||||
if (new_position < current_position) {
|
|
||||||
lseek(fd_, current_position, SEEK_SET);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return new_position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a request to read bytes.
|
size_t remaining = length_ - offset_;
|
||||||
return ::read(fd_, buffer, size);
|
if (size > remaining)
|
||||||
|
size = remaining;
|
||||||
|
memcpy(buffer, memory_ + offset_, size);
|
||||||
|
offset_ += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const void* getMemoryBase() {
|
||||||
|
return memory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int fd_;
|
const uint8_t* memory_;
|
||||||
|
size_t offset_, length_;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user