diff options
author | 2008-10-21 07:00:00 -0700 | |
---|---|---|
committer | 2008-10-21 07:00:00 -0700 | |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /libs/surfaceflinger/VRamHeap.cpp |
Initial Contribution
Diffstat (limited to 'libs/surfaceflinger/VRamHeap.cpp')
-rw-r--r-- | libs/surfaceflinger/VRamHeap.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp new file mode 100644 index 000000000000..3852d51954a5 --- /dev/null +++ b/libs/surfaceflinger/VRamHeap.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SurfaceFlinger" + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <math.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> + +#include <cutils/log.h> +#include <cutils/properties.h> + +#include <utils/MemoryDealer.h> +#include <utils/MemoryBase.h> +#include <utils/MemoryHeapPmem.h> +#include <utils/MemoryHeapBase.h> + +#include <GLES/eglnatives.h> + +#include "VRamHeap.h" + +#if HAVE_ANDROID_OS +#include <linux/android_pmem.h> +#endif + + +namespace android { + +// --------------------------------------------------------------------------- + +/* + * Amount of memory we reserve for surface, per client in PMEM + * (PMEM is used for 2D acceleration) + * 8 MB of address space per client should be enough. + */ +static const int PMEM_SIZE = int(8 * 1024 * 1024); + +int SurfaceHeapManager::global_pmem_heap = 0; + +// --------------------------------------------------------------------------- + +SurfaceHeapManager::SurfaceHeapManager(size_t clientHeapSize) + : mClientHeapSize(clientHeapSize) +{ + SurfaceHeapManager::global_pmem_heap = 1; +} + +SurfaceHeapManager::~SurfaceHeapManager() +{ +} + +void SurfaceHeapManager::onFirstRef() +{ + if (global_pmem_heap) { + const char* device = "/dev/pmem"; + mPMemHeap = new PMemHeap(device, PMEM_SIZE); + if (mPMemHeap->base() == MAP_FAILED) { + mPMemHeap.clear(); + global_pmem_heap = 0; + } + } +} + +sp<MemoryDealer> SurfaceHeapManager::createHeap(int type) +{ + if (!global_pmem_heap && type==NATIVE_MEMORY_TYPE_PMEM) + type = NATIVE_MEMORY_TYPE_HEAP; + + const sp<PMemHeap>& heap(mPMemHeap); + sp<MemoryDealer> dealer; + switch (type) { + case NATIVE_MEMORY_TYPE_HEAP: + dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap"); + break; + + case NATIVE_MEMORY_TYPE_PMEM: + if (heap != 0) { + dealer = new MemoryDealer( + heap->createClientHeap(), + heap->getAllocator()); + } + break; + } + return dealer; +} + +sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const +{ + Mutex::Autolock _l(mLock); + sp<SimpleBestFitAllocator> allocator; + + // this is only used for debugging + switch (type) { + case NATIVE_MEMORY_TYPE_PMEM: + if (mPMemHeap != 0) { + allocator = mPMemHeap->getAllocator(); + } + break; + } + return allocator; +} + +// --------------------------------------------------------------------------- + +PMemHeapInterface::PMemHeapInterface(int fd, size_t size) + : MemoryHeapBase(fd, size) { +} +PMemHeapInterface::PMemHeapInterface(const char* device, size_t size) + : MemoryHeapBase(device, size) { +} +PMemHeapInterface::PMemHeapInterface(size_t size, uint32_t flags, char const * name) + : MemoryHeapBase(size, flags, name) { +} +PMemHeapInterface::~PMemHeapInterface() { +} + +// --------------------------------------------------------------------------- + +PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved) + : PMemHeapInterface(device, size) +{ + //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); + if (base() != MAP_FAILED) { + //LOGD("%s, %u bytes", device, virtualSize()); + if (reserved == 0) + reserved = virtualSize(); + mAllocator = new SimpleBestFitAllocator(reserved); + } +} + +PMemHeap::~PMemHeap() { + //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID()); +} + +sp<MemoryHeapPmem> PMemHeap::createClientHeap() { + sp<MemoryHeapBase> parentHeap(this); + return new MemoryHeapPmem(parentHeap); +} + +// --------------------------------------------------------------------------- +}; // namespace android |