/*
 * Copyright (C) 2007 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 "Surface"

#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/threads.h>
#include <binder/IPCThreadState.h>
#include <binder/IMemory.h>
#include <utils/Log.h>

#include <ui/ISurface.h>
#include <ui/Surface.h>
#include <ui/SurfaceComposerClient.h>
#include <ui/Rect.h>

#include <private/ui/SharedState.h>
#include <private/ui/LayerState.h>

namespace android {

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

Surface::Surface(const sp<SurfaceComposerClient>& client, 
        const sp<ISurface>& surface,
        const ISurfaceFlingerClient::surface_data_t& data,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        bool owner)
    : mClient(client), mSurface(surface),
      mToken(data.token), mIdentity(data.identity),
      mFormat(format), mFlags(flags), mOwner(owner)
{
    mSwapRectangle.makeInvalid();
    mSurfaceHeapBase[0] = 0;
    mSurfaceHeapBase[1] = 0;
    mHeap[0] = data.heap[0]; 
    mHeap[1] = data.heap[1];
}

Surface::Surface(Surface const* rhs)
    : mOwner(false)
{
    mToken   = rhs->mToken;
    mIdentity= rhs->mIdentity;
    mClient  = rhs->mClient;
    mSurface = rhs->mSurface;
    mHeap[0] = rhs->mHeap[0];
    mHeap[1] = rhs->mHeap[1];
    mFormat  = rhs->mFormat;
    mFlags   = rhs->mFlags;
    mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
    mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1];
    mSwapRectangle.makeInvalid();
}

Surface::~Surface()
{
    if (mOwner && mToken>=0 && mClient!=0) {
        mClient->destroySurface(mToken);
    }
    mClient.clear();
    mSurface.clear();
    mHeap[0].clear();
    mHeap[1].clear();
    IPCThreadState::self()->flushCommands();
}

sp<Surface> Surface::dup() const
{
    Surface const * r = this;
    if (this && mOwner) {
        // the only reason we need to do this is because of Java's garbage
        // collector: because we're creating a copy of the Surface
        // instead of a reference, we can garantee that when our last
        // reference goes away, the real surface will be deleted.
        // Without this hack (the code is correct too), we'd have to
        // wait for a GC for the surface to go away.
        r = new Surface(this);        
    }
    return const_cast<Surface*>(r);
}

status_t Surface::nextBuffer(SurfaceInfo* info) {
    return mClient->nextBuffer(this, info);
}

status_t Surface::lock(SurfaceInfo* info, bool blocking) {
    return Surface::lock(info, NULL, blocking);
}

status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) {
    if (heapBase(0) == 0) return INVALID_OPERATION;
    if (heapBase(1) == 0) return INVALID_OPERATION;
    return mClient->lockSurface(this, info, dirty, blocking);
}

status_t Surface::unlockAndPost() {
    if (heapBase(0) == 0) return INVALID_OPERATION;
    if (heapBase(1) == 0) return INVALID_OPERATION;
    return mClient->unlockAndPostSurface(this);
}

status_t Surface::unlock() {
    if (heapBase(0) == 0) return INVALID_OPERATION;
    if (heapBase(1) == 0) return INVALID_OPERATION;
    return mClient->unlockSurface(this);
}

status_t Surface::setLayer(int32_t layer) {
    return mClient->setLayer(this, layer);
}
status_t Surface::setPosition(int32_t x, int32_t y) {
    return mClient->setPosition(this, x, y);
}
status_t Surface::setSize(uint32_t w, uint32_t h) {
    return mClient->setSize(this, w, h);
}
status_t Surface::hide() {
    return mClient->hide(this);
}
status_t Surface::show(int32_t layer) {
    return mClient->show(this, layer);
}
status_t Surface::freeze() {
    return mClient->freeze(this);
}
status_t Surface::unfreeze() {
    return mClient->unfreeze(this);
}
status_t Surface::setFlags(uint32_t flags, uint32_t mask) {
    return mClient->setFlags(this, flags, mask);
}
status_t Surface::setTransparentRegionHint(const Region& transparent) {
    return mClient->setTransparentRegionHint(this, transparent);
}
status_t Surface::setAlpha(float alpha) {
    return mClient->setAlpha(this, alpha);
}
status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy);
}
status_t Surface::setFreezeTint(uint32_t tint) {
    return mClient->setFreezeTint(this, tint);
}

Region Surface::dirtyRegion() const  {
    return mDirtyRegion; 
}
void Surface::setDirtyRegion(const Region& region) const {
    mDirtyRegion = region;
}
const Rect& Surface::swapRectangle() const {
    return mSwapRectangle;
}
void Surface::setSwapRectangle(const Rect& r) {
    mSwapRectangle = r;
}

sp<Surface> Surface::readFromParcel(Parcel* parcel)
{
    sp<SurfaceComposerClient> client;
    ISurfaceFlingerClient::surface_data_t data;
    sp<IBinder> clientBinder= parcel->readStrongBinder();
    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
    data.heap[0]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
    data.heap[1]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
    data.token              = parcel->readInt32();
    data.identity           = parcel->readInt32();
    PixelFormat format      = parcel->readInt32();
    uint32_t flags          = parcel->readInt32();

    if (clientBinder != NULL)
        client = SurfaceComposerClient::clientForConnection(clientBinder);

    return new Surface(client, surface, data, 0, 0, format, flags, false);
}

status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
{
    uint32_t flags=0;
    uint32_t format=0;
    SurfaceID token = -1;
    uint32_t identity = 0;
    sp<SurfaceComposerClient> client;
    sp<ISurface> sur;
    sp<IMemoryHeap> heap[2];
    if (surface->isValid()) {
        token = surface->mToken;
        identity = surface->mIdentity;
        client = surface->mClient;
        sur = surface->mSurface;
        heap[0] = surface->mHeap[0];
        heap[1] = surface->mHeap[1];
        format = surface->mFormat;
        flags = surface->mFlags;
    }
    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder()  : NULL);
    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder()  : NULL);
    parcel->writeInt32(token);
    parcel->writeInt32(identity);
    parcel->writeInt32(format);
    parcel->writeInt32(flags);
    return NO_ERROR;
}

bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) 
{
    if (lhs == 0 || rhs == 0)
        return false;
    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
}

void* Surface::heapBase(int i) const 
{
    void* heapBase = mSurfaceHeapBase[i];
    // map lazily so it doesn't get mapped in clients that don't need it
    if (heapBase == 0) {
        const sp<IMemoryHeap>& heap(mHeap[i]);
        if (heap != 0) {
            heapBase = static_cast<uint8_t*>(heap->base());
            if (heapBase == MAP_FAILED) {
                heapBase = NULL;
                LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)",
                        heap->asBinder().get(), heap.get());
            }
            mSurfaceHeapBase[i] = heapBase;
        }
    }
    return heapBase;
}

}; // namespace android

