Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 082e3be0 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "added setCrop() to android_native_window_t" into kraken

parents f2d283de cc08e688
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -70,9 +70,9 @@ class SharedClient;
// ----------------------------------------------------------------------------

// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX
// 4 * (11 + 7 + (1 + 2*6)*16) * 31
// 904 * 31
// = ~27 KiB (28024)
// 4 * (11 + 7 + (1 + 2*7)*16) * 31
// 1032 * 31
// = ~27 KiB (31992)

class SharedBufferStack
{
@@ -82,21 +82,31 @@ class SharedBufferStack
    friend class SharedBufferServer;

public:
    struct Statistics { // 4 longs
        typedef int32_t usecs_t;
        usecs_t  totalTime;
        usecs_t  reserved[3];
    };

    struct SmallRect {
        uint16_t l, t, r, b;
    };

    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
        static const unsigned int NUM_RECT_MAX = 6;
        uint32_t    count;
        uint16_t    rects[4*NUM_RECT_MAX];
        SmallRect   rects[NUM_RECT_MAX];
    };
    
    struct Statistics { // 4 longs
        typedef int32_t usecs_t;
        usecs_t  totalTime;
        usecs_t  reserved[3];
    struct BufferData {
        FlatRegion dirtyRegion;
        SmallRect  crop;
    };
    
    SharedBufferStack();
    void init(int32_t identity);
    status_t setDirtyRegion(int buffer, const Region& reg);
    status_t setCrop(int buffer, const Rect& reg);
    Region getDirtyRegion(int buffer) const;

    // these attributes are part of the conditions/updates
@@ -113,7 +123,7 @@ public:
    int32_t     reserved32[6];
    Statistics  stats;
    int32_t     reserved;
    FlatRegion  dirtyRegion[NUM_BUFFER_MAX]; // 832 bytes
    BufferData  buffers[NUM_BUFFER_MAX];     // 960 bytes
};

// ----------------------------------------------------------------------------
@@ -243,6 +253,7 @@ public:
    status_t queue(int buf);
    bool needNewBuffer(int buffer) const;
    status_t setDirtyRegion(int buffer, const Region& reg);
    status_t setCrop(int buffer, const Rect& reg);
    
private:
    friend struct Condition;
+9 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ public:
    
    virtual sp<IMemoryHeap> getControlBlock() const = 0;

    /*
     * Requires ACCESS_SURFACE_FLINGER permission
     */
    virtual sp<ISurface> createSurface( surface_data_t* data,
                                        int pid, 
                                        const String8& name,
@@ -68,8 +71,14 @@ public:
                                        PixelFormat format,
                                        uint32_t flags) = 0;
                                    
    /*
     * Requires ACCESS_SURFACE_FLINGER permission
     */
    virtual status_t    destroySurface(SurfaceID sid) = 0;

    /*
     * Requires ACCESS_SURFACE_FLINGER permission
     */
    virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
};

+3 −0
Original line number Diff line number Diff line
@@ -215,10 +215,12 @@ private:
    void dispatch_setUsage(va_list args);
    int  dispatch_connect(va_list args);
    int  dispatch_disconnect(va_list args);
    int  dispatch_crop(va_list args);
    
    void setUsage(uint32_t reqUsage);
    int  connect(int api);
    int  disconnect(int api);
    int  crop(Rect const* rect);

    uint32_t getUsage() const;
    int      getConnectedApi() const;
@@ -237,6 +239,7 @@ private:
    Rect                        mSwapRectangle;
    uint32_t                    mUsage;
    int                         mConnected;
    Rect                        mNextBufferCrop;
    
    // protected by mSurfaceLock. These are also used from lock/unlock
    // but in that case, they must be called form the same thread.
+33 −5
Original line number Diff line number Diff line
@@ -41,6 +41,14 @@ extern "C" {

struct android_native_buffer_t;

typedef struct android_native_rect_t
{
    int32_t left;
    int32_t top;
    int32_t right;
    int32_t bottom;
} android_native_rect_t;

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

typedef struct android_native_base_t
@@ -63,15 +71,16 @@ typedef struct android_native_base_t
/* attributes queriable with query() */
enum {
    NATIVE_WINDOW_WIDTH     = 0,
    NATIVE_WINDOW_HEIGHT    = 1,
    NATIVE_WINDOW_FORMAT    = 2,
    NATIVE_WINDOW_HEIGHT,
    NATIVE_WINDOW_FORMAT,
};

/* valid operations for the (*perform)() hook */
enum {
    NATIVE_WINDOW_SET_USAGE  = 0,
    NATIVE_WINDOW_CONNECT    = 1,
    NATIVE_WINDOW_DISCONNECT = 2
    NATIVE_WINDOW_CONNECT,
    NATIVE_WINDOW_DISCONNECT,
    NATIVE_WINDOW_SET_CROP,
};

/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -171,6 +180,7 @@ typedef struct android_native_window_t
     *     NATIVE_WINDOW_SET_USAGE
     *     NATIVE_WINDOW_CONNECT
     *     NATIVE_WINDOW_DISCONNECT
     *     NATIVE_WINDOW_SET_CROP
     *  
     */
    
@@ -221,6 +231,24 @@ static inline int native_window_disconnect(
    return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
}

/*
 * native_window_set_crop(..., crop) sets which region of the next queued
 * buffers needs to be considered.
 * A buffer's crop region is scaled to match the surface's size.
 *
 * The specified crop region applies to all buffers queued after it is called.
 *
 * if 'crop' is NULL, subsequently queued buffers won't be cropped.
 *
 * An error is returned if for instance the crop region is invalid,
 * out of the buffer's bound or if the window is invalid.
 */
static inline int native_window_set_crop(
        android_native_window_t* window,
        android_native_rect_t const * crop)
{
    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
}

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

+39 −16
Original line number Diff line number Diff line
@@ -67,6 +67,18 @@ void SharedBufferStack::init(int32_t i)
    identity = i;
}

status_t SharedBufferStack::setCrop(int buffer, const Rect& crop)
{
    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
        return BAD_INDEX;

    buffers[buffer].crop.l = uint16_t(crop.left);
    buffers[buffer].crop.t = uint16_t(crop.top);
    buffers[buffer].crop.r = uint16_t(crop.right);
    buffers[buffer].crop.b = uint16_t(crop.bottom);
    return NO_ERROR;
}

status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
{
    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
@@ -75,21 +87,21 @@ status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
    // in the current implementation we only send a single rectangle
    size_t count;
    Rect const* r = dirty.getArray(&count);
    FlatRegion& reg(dirtyRegion[buffer]);
    FlatRegion& reg(buffers[buffer].dirtyRegion);
    if (count > FlatRegion::NUM_RECT_MAX) {
        const Rect bounds(dirty.getBounds());
        reg.count = 1;
        reg.rects[0] = uint16_t(bounds.left);
        reg.rects[1] = uint16_t(bounds.top);
        reg.rects[2] = uint16_t(bounds.right);
        reg.rects[3] = uint16_t(bounds.bottom);
        reg.rects[0].l = uint16_t(bounds.left);
        reg.rects[0].t = uint16_t(bounds.top);
        reg.rects[0].r = uint16_t(bounds.right);
        reg.rects[0].b = uint16_t(bounds.bottom);
    } else {
        reg.count = count;
        for (size_t i=0 ; i<count ; i++) {
            reg.rects[i*4 + 0] = uint16_t(r[i].left);
            reg.rects[i*4 + 1] = uint16_t(r[i].top);
            reg.rects[i*4 + 2] = uint16_t(r[i].right);
            reg.rects[i*4 + 3] = uint16_t(r[i].bottom);
            reg.rects[i].l = uint16_t(r[i].left);
            reg.rects[i].t = uint16_t(r[i].top);
            reg.rects[i].r = uint16_t(r[i].right);
            reg.rects[i].b = uint16_t(r[i].bottom);
        }
    }
    return NO_ERROR;
@@ -101,19 +113,24 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const
    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
        return res;

    const FlatRegion& reg(dirtyRegion[buffer]);
    const FlatRegion& reg(buffers[buffer].dirtyRegion);
    if (reg.count > FlatRegion::NUM_RECT_MAX)
        return res;

    if (reg.count == 1) {
        res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3]));
        const Rect r(
                reg.rects[0].l,
                reg.rects[0].t,
                reg.rects[0].r,
                reg.rects[0].b);
        res.set(r);
    } else {
        for (size_t i=0 ; i<reg.count ; i++) {
            const Rect r(
                    reg.rects[i*4 + 0],
                    reg.rects[i*4 + 1],
                    reg.rects[i*4 + 2],
                    reg.rects[i*4 + 3]);
                    reg.rects[i].l,
                    reg.rects[i].t,
                    reg.rects[i].r,
                    reg.rects[i].b);
            res.orSelf(r);
        }
    }
@@ -372,6 +389,12 @@ bool SharedBufferClient::needNewBuffer(int buffer) const
    return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
}

status_t SharedBufferClient::setCrop(int buffer, const Rect& crop)
{
    SharedBufferStack& stack( *mSharedStack );
    return stack.setCrop(buffer, crop);
}

status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
{
    SharedBufferStack& stack( *mSharedStack );
@@ -389,7 +412,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
    mSharedStack->available = num;
    mSharedStack->queued = 0;
    mSharedStack->reallocMask = 0;
    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
    memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
}

ssize_t SharedBufferServer::retireAndLock()
Loading