/*
 * 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 "GPUHardware/GPUHardware.h"
#include "SurfaceFlinger.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(const sp<SurfaceFlinger>& flinger, 
        size_t clientHeapSize)
    : mFlinger(flinger), 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(
        uint32_t flags,
        pid_t client_pid,
        const sp<MemoryDealer>& defaultAllocator)
{
    sp<MemoryDealer> dealer; 

    if (flags & ISurfaceComposer::eGPU) {
        // don't grant GPU memory if GPU is disabled
        char value[PROPERTY_VALUE_MAX];
        property_get("debug.egl.hw", value, "1");
        if (atoi(value) == 0) {
            flags &= ~ISurfaceComposer::eGPU;
        }
    }

    if (flags & ISurfaceComposer::eGPU) {
        // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
        if (!(flags & ISurfaceComposer::eSecure)) {
            // if GPU doesn't work, we try eHardware
            flags |= ISurfaceComposer::eHardware;
            // asked for GPU memory, try that first
            dealer = mFlinger->getGPU()->request(client_pid);
        }
    }

    if (dealer == NULL) {
        if (defaultAllocator != NULL)
            // if a default allocator is given, use that
            dealer = defaultAllocator;
    }
    
    if (dealer == NULL) {
        // always try h/w accelerated memory first
        if (global_pmem_heap) {
            const sp<PMemHeap>& heap(mPMemHeap);
            if (dealer == NULL && heap != NULL) {
                dealer = new MemoryDealer( 
                        heap->createClientHeap(),
                        heap->getAllocator());
            }
        }
    }

    if (dealer == NULL) {
        // return the ashmem allocator (software rendering)
        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
    }
    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;
}

// ---------------------------------------------------------------------------

PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
    : MemoryHeapBase(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
