OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <unistd.h> | 8 #include <unistd.h> |
9 #include <sys/mman.h> | 9 #include <sys/mman.h> |
10 #include "SkDiscardableMemory.h" | 10 #include "SkDiscardableMemory.h" |
| 11 #include "SkDiscardableMemoryPool.h" |
11 #include "SkTypes.h" | 12 #include "SkTypes.h" |
12 #include "android/ashmem.h" | 13 #include "android/ashmem.h" |
13 | 14 |
14 //////////////////////////////////////////////////////////////////////////////// | 15 //////////////////////////////////////////////////////////////////////////////// |
15 namespace { | 16 namespace { |
16 /** | 17 /** |
17 * DiscardableMemory implementation that uses the Android kernel's | 18 * DiscardableMemory implementation that uses the Android kernel's |
18 * ashmem (Android shared memory). | 19 * ashmem (Android shared memory). |
19 */ | 20 */ |
20 class SkAshmemDiscardableMemory : public SkDiscardableMemory { | 21 class SkAshmemDiscardableMemory : public SkDiscardableMemory { |
21 public: | 22 public: |
22 SkAshmemDiscardableMemory(int fd, void* address, size_t size); | 23 SkAshmemDiscardableMemory(int fd, void* address, size_t size); |
23 virtual ~SkAshmemDiscardableMemory(); | 24 virtual ~SkAshmemDiscardableMemory(); |
24 virtual bool lock() SK_OVERRIDE; | 25 virtual bool lock() SK_OVERRIDE; |
25 virtual void* data() SK_OVERRIDE; | 26 virtual void* data() SK_OVERRIDE; |
26 virtual void unlock() SK_OVERRIDE; | 27 virtual void unlock() SK_OVERRIDE; |
| 28 static SkAshmemDiscardableMemory* Create(size_t bytes); |
| 29 |
27 private: | 30 private: |
28 bool fLocked; | 31 bool fLocked; |
29 int fFd; | 32 int fFd; |
30 void* fMemory; | 33 void* fMemory; |
31 const size_t fSize; | 34 const size_t fSize; |
32 }; | 35 }; |
33 | 36 |
34 SkAshmemDiscardableMemory::SkAshmemDiscardableMemory(int fd, | 37 SkAshmemDiscardableMemory::SkAshmemDiscardableMemory(int fd, |
35 void* address, | 38 void* address, |
36 size_t size) | 39 size_t size) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 return fLocked ? fMemory : NULL; | 82 return fLocked ? fMemory : NULL; |
80 } | 83 } |
81 | 84 |
82 void SkAshmemDiscardableMemory::unlock() { | 85 void SkAshmemDiscardableMemory::unlock() { |
83 SkASSERT(fLocked); | 86 SkASSERT(fLocked); |
84 if (fLocked && (fFd != -1)) { | 87 if (fLocked && (fFd != -1)) { |
85 ashmem_unpin_region(fFd, 0, 0); | 88 ashmem_unpin_region(fFd, 0, 0); |
86 } | 89 } |
87 fLocked = false; | 90 fLocked = false; |
88 } | 91 } |
89 } // namespace | |
90 //////////////////////////////////////////////////////////////////////////////// | |
91 | 92 |
92 SkDiscardableMemory* SkDiscardableMemory::Create(size_t bytes) { | 93 SkAshmemDiscardableMemory* SkAshmemDiscardableMemory::Create(size_t bytes) { |
93 // ashmem likes lengths on page boundaries. | 94 // ashmem likes lengths on page boundaries. |
94 const size_t mask = getpagesize() - 1; | 95 const size_t mask = getpagesize() - 1; |
95 size_t size = (bytes + mask) & ~mask; | 96 size_t size = (bytes + mask) & ~mask; |
96 | 97 |
97 static const char name[] = "Skia_Ashmem_Discardable_Memory"; | 98 static const char name[] = "Skia_Ashmem_Discardable_Memory"; |
98 int fd = ashmem_create_region(name, size); | 99 int fd = ashmem_create_region(name, size); |
99 if (fd < 0) { | 100 if (fd < 0) { |
100 return NULL; | 101 return NULL; |
101 } | 102 } |
102 if (0 != ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE)) { | 103 if (0 != ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE)) { |
103 close(fd); | 104 close(fd); |
104 return NULL; | 105 return NULL; |
105 } | 106 } |
106 void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | 107 void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); |
107 if ((MAP_FAILED == addr) || (NULL == addr)) { | 108 if ((MAP_FAILED == addr) || (NULL == addr)) { |
108 close(fd); | 109 close(fd); |
109 return NULL; | 110 return NULL; |
110 } | 111 } |
111 | 112 |
112 return SkNEW_ARGS(SkAshmemDiscardableMemory, (fd, addr, size)); | 113 return SkNEW_ARGS(SkAshmemDiscardableMemory, (fd, addr, size)); |
113 } | 114 } |
| 115 } // namespace |
| 116 //////////////////////////////////////////////////////////////////////////////// |
| 117 |
| 118 #ifndef SK_ASHMEM_MINIMUM_MEMORY_SIZE |
| 119 // number taken from android/graphics/BitmapFactory.cpp |
| 120 #define SK_ASHMEM_MINIMUM_MEMORY_SIZE (32 * 1024) |
| 121 #endif // SK_ASHMEM_MINIMUM_MEMORY_SIZE |
| 122 SkDiscardableMemory* SkDiscardableMemory::Create(size_t bytes) { |
| 123 if (bytes < SK_ASHMEM_MINIMUM_MEMORY_SIZE) { |
| 124 return SkGetGlobalDiscardableMemoryPool()->create(bytes); |
| 125 } else { |
| 126 return SkAshmemDiscardableMemory::Create(bytes); |
| 127 } |
| 128 } |
| 129 |
OLD | NEW |