/*
 * 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.
 */

#ifndef ANDROID_UI_SHARED_STATE_H
#define ANDROID_UI_SHARED_STATE_H

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

#include <utils/threads.h>

namespace android {

/*
 * These structures are shared between the composer process and its clients
 */

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

struct surface_info_t { // 4 longs, 16 bytes
    enum {
        eBufferDirty    = 0x01
    };
    uint16_t    w;
    uint16_t    h;
    uint16_t    stride;
    uint16_t    bpr;
    uint16_t    reserved;
    uint8_t     format;
    uint8_t     flags;
    ssize_t     bits_offset;
};

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

const uint32_t NUM_LAYERS_MAX = 31;

enum { // layer_cblk_t swapState
    eIndex              = 0x00000001,
    eFlipRequested      = 0x00000002,
    
    eResizeBuffer0      = 0x00000004,
    eResizeBuffer1      = 0x00000008,    
    eResizeRequested    = eResizeBuffer0 | eResizeBuffer1,
    
    eBusy               = 0x00000010,
    eLocked             = 0x00000020,
    eNextFlipPending    = 0x00000040,    
    eInvalidSurface     = 0x00000080
};

enum { // layer_cblk_t flags
    eLayerNotPosted     = 0x00000001,
    eNoCopyBack         = 0x00000002,
    eReserved           = 0x0000007C,
    eBufferIndexShift   = 7,
    eBufferIndex        = 1<<eBufferIndexShift,
};

struct flat_region_t    // 40 bytes
{
    int32_t     count;
    int16_t     l;
    int16_t     t;
    int16_t     r;
    int16_t     b;
    uint16_t    runs[14];
};

struct layer_cblk_t     // (128 bytes)
{
    volatile    int32_t             swapState;      //  4
    volatile    int32_t             flags;          //  4
    volatile    int32_t             identity;       //  4
                int32_t             reserved;       //  4
                surface_info_t      surface[2];     // 32
                flat_region_t       region[2];      // 80

    static inline int backBuffer(uint32_t state) {
        return ((state & eIndex) ^ ((state & eFlipRequested)>>1));
    }
    static inline int frontBuffer(uint32_t state) {
        return 1 - backBuffer(state);
    }
};

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

struct per_client_cblk_t   // 4KB max
{
                Mutex           lock;
                Condition       cv;
                layer_cblk_t    layers[NUM_LAYERS_MAX] __attribute__((aligned(32)));

    enum {
        BLOCKING = 0x00000001,
        INSPECT  = 0x00000002
    };

    per_client_cblk_t();

    // these functions are used by the clients
    status_t validate(size_t i) const;
    int32_t lock_layer(size_t i, uint32_t flags);
    uint32_t unlock_layer_and_post(size_t i);
    void unlock_layer(size_t i);
};
// ---------------------------------------------------------------------------

const uint32_t NUM_DISPLAY_MAX = 4;

struct display_cblk_t
{
    uint16_t    w;
    uint16_t    h;
    uint8_t     format;
    uint8_t     orientation;
    uint8_t     reserved[2];
    float       fps;
    float       density;
    float       xdpi;
    float       ydpi;
    uint32_t    pad[2];
};

struct surface_flinger_cblk_t   // 4KB max
{
    surface_flinger_cblk_t();
    
    uint8_t         connected;
    uint8_t         reserved[3];
    uint32_t        pad[7];
 
    display_cblk_t  displays[NUM_DISPLAY_MAX];
};

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

template<bool> struct CTA;
template<> struct CTA<true> { };

// compile-time assertions. just to avoid catastrophes.
inline void compile_time_asserts() {
    CTA<sizeof(layer_cblk_t) == 128> sizeof__layer_cblk_t__eq_128;
    (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning
    CTA<sizeof(per_client_cblk_t) <= 4096> sizeof__per_client_cblk_t__le_4096;
    (void)sizeof__per_client_cblk_t__le_4096;  // we don't want a warning
    CTA<sizeof(surface_flinger_cblk_t) <= 4096> sizeof__surface_flinger_cblk_t__le_4096;
    (void)sizeof__surface_flinger_cblk_t__le_4096;  // we don't want a warning
}

}; // namespace android

#endif // ANDROID_UI_SHARED_STATE_H

