/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "VRamHeap.h" #if HAVE_ANDROID_OS #include #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 SurfaceHeapManager::createHeap(int type) { if (!global_pmem_heap && type==NATIVE_MEMORY_TYPE_PMEM) type = NATIVE_MEMORY_TYPE_HEAP; const sp& heap(mPMemHeap); sp 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 SurfaceHeapManager::getAllocator(int type) const { Mutex::Autolock _l(mLock); sp 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 PMemHeap::createClientHeap() { sp parentHeap(this); return new MemoryHeapPmem(parentHeap); } // --------------------------------------------------------------------------- }; // namespace android