/*
 * Copyright (C) 2006 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.
 */

#ifndef ANDROID_ISURFACE_COMPOSER_H
#define ANDROID_ISURFACE_COMPOSER_H

#include <stdint.h>
#include <sys/types.h>

#include <utils/RefBase.h>
#include <utils/Errors.h>
#include <utils/IInterface.h>

#include <ui/PixelFormat.h>
#include <ui/ISurfaceFlingerClient.h>

namespace android {

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

class DisplayInfo;
class IGPUCallback;

class ISurfaceComposer : public IInterface
{
public:
    DECLARE_META_INTERFACE(SurfaceComposer);

    enum { // (keep in sync with Surface.java)
        eHidden             = 0x00000004,
        eGPU                = 0x00000008,
        eHardware           = 0x00000010,
        eDestroyBackbuffer  = 0x00000020,
        eSecure             = 0x00000080,
        eNonPremultiplied   = 0x00000100,
        ePushBuffers        = 0x00000200,

        eFXSurfaceNormal    = 0x00000000,
        eFXSurfaceBlur      = 0x00010000,
        eFXSurfaceDim       = 0x00020000,
        eFXSurfaceMask      = 0x000F0000,
    };

    enum {
        ePositionChanged            = 0x00000001,
        eLayerChanged               = 0x00000002,
        eSizeChanged                = 0x00000004,
        eAlphaChanged               = 0x00000008,
        eMatrixChanged              = 0x00000010,
        eTransparentRegionChanged   = 0x00000020,
        eVisibilityChanged          = 0x00000040,
        eFreezeTintChanged          = 0x00000080,
        eDestroyed                  = 0x00000100
    };

    enum {
        eLayerHidden        = 0x01,
        eLayerFrozen        = 0x02,
        eLayerDither        = 0x04,
        eLayerFilter        = 0x08,
        eLayerBlurFreeze    = 0x10
    };

    enum {
        eOrientationDefault     = 0,
        eOrientation90          = 1,
        eOrientation180         = 2,
        eOrientation270         = 3,
        eOrientationSwapMask    = 0x01
    };

    /* create connection with surface flinger, requires
     * ACCESS_SURFACE_FLINGER permission
     */

    virtual sp<ISurfaceFlingerClient> createConnection() = 0;

    /* retrieve the control block */
    virtual sp<IMemory> getCblk() const = 0;

    /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */
    virtual void openGlobalTransaction() = 0;
    virtual void closeGlobalTransaction() = 0;

    /* [un]freeze display. recquires ACCESS_SURFACE_FLINGER permission */
    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;

    /* Set display orientation. recquires ACCESS_SURFACE_FLINGER permission */
    virtual int setOrientation(DisplayID dpy, int orientation) = 0;

    /* signal that we're done booting.
     * recquires ACCESS_SURFACE_FLINGER permission
     */
    virtual void bootFinished() = 0;

    /* get access to the GPU. Access is relinquished when releasing regs */
    struct gpu_info_t {
        struct gpu_region_t {
            sp<IMemory> region;
            size_t reserved;
        };
        sp<IMemory>             regs;
        size_t                  count;
        gpu_region_t            regions[2];
    };
    virtual status_t requestGPU(
            const sp<IGPUCallback>& callback,
            gpu_info_t* gpu) = 0;

    /* take the gpu back from any apps using it. They'll get a
     * EGL_CONTEXT_LOST error */
    virtual status_t revokeGPU() = 0;

    /* Signal surfaceflinger that there might be some work to do
     * This is an ASYNCHRONOUS call.
     */
    virtual void signal() const = 0;
};

class IGPUCallback : public IInterface
{
public:
    DECLARE_META_INTERFACE(GPUCallback);
    virtual void gpuLost() = 0; //one-way
};

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

class BnSurfaceComposer : public BnInterface<ISurfaceComposer>
{
public:
    enum {
        // Note: BOOT_FINISHED must remain this value, it is called from
        // Java by ActivityManagerService.
        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
        CREATE_CONNECTION,
        GET_CBLK,
        OPEN_GLOBAL_TRANSACTION,
        CLOSE_GLOBAL_TRANSACTION,
        SET_ORIENTATION,
        FREEZE_DISPLAY,
        UNFREEZE_DISPLAY,
        REQUEST_GPU,
        REVOKE_GPU,
        SIGNAL
    };

    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

class BnGPUCallback : public BnInterface<IGPUCallback>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

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

}; // namespace android

#endif // ANDROID_ISURFACE_COMPOSER_H
