SurfaceComposerClient.cpp revision 076b1cc3a9b90aa5b381a1ed268ca0b548444c9b
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "SurfaceComposerClient"
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/memory.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Atomic.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/KeyedVector.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IServiceManager.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IMemory.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurfaceComposer.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurfaceFlingerClient.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h>
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/SharedState.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h>
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/SurfaceFlingerSynchro.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define VERBOSE(...)	((void)0)
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//#define VERBOSE			LOGD
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic Mutex                                                gLock;
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic sp<ISurfaceComposer>                                 gSurfaceManager;
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic sp<IMemory>                                          gServerCblkMemory;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile surface_flinger_cblk_t*                     gServerCblk;
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst sp<ISurfaceComposer>& _get_surface_manager()
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (gSurfaceManager != 0) {
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return gSurfaceManager;
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<IBinder> binder;
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<IServiceManager> sm = defaultServiceManager();
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    do {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        binder = sm->getService(String16("SurfaceFlinger"));
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (binder == 0) {
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGW("SurfaceFlinger not published, waiting...");
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            usleep(500000); // 0.5 s
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } while(binder == 0);
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(gLock);
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (gSurfaceManager == 0) {
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gSurfaceManager = sc;
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return gSurfaceManager;
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile surface_flinger_cblk_t const * get_cblk()
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (gServerCblk == 0) {
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurfaceComposer>& sm(_get_surface_manager());
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Mutex::Autolock _l(gLock);
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (gServerCblk == 0) {
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gServerCblkMemory = sm->getCblk();
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGE_IF(gServerCblk==0, "Can't get server control block address");
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return gServerCblk;
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// these functions are used by the clients
107076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t per_client_cblk_t::validate(size_t i) const {
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(i) >= NUM_LAYERS_MAX)
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_INDEX;
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layers[i].swapState & eInvalidSurface)
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_MEMORY;
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t index;
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t state;
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int timeout = 0;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t result;
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_cblk_t * const layer = layers + i;
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool blocking = flags & BLOCKING;
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool inspect  = flags & INSPECT;
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    do {
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        state = layer->swapState;
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGE("eNextFlipPending set but eFlipRequested not set, "
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 "layer=%d (lcblk=%p), state=%08x",
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 int(i), layer, int(state));
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return INVALID_OPERATION;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (UNLIKELY(state&eLocked)) {
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGE("eLocked set when entering lock_layer(), "
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 "layer=%d (lcblk=%p), state=%08x",
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 int(i), layer, int(state));
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return WOULD_BLOCK;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        | eInvalidSurface))
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        int32_t resizeIndex;
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        Mutex::Autolock _l(lock);
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            // might block for a very short amount of time
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            // will never cause the server to block (trylock())
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        goto start_loop_here;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        // We block the client if:
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        // eNextFlipPending:  we've used both buffers already, so we need to
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        //                    wait for one to become availlable.
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        // eResizeRequested:  the buffer we're going to acquire is being
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        //                    resized. Block until it is done.
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        // eFlipRequested && eBusy: the buffer we're going to acquire is
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        //                    currently in use by the server.
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        // eInvalidSurface:   this is a special case, we don't block in this
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        //                    case, we just return an error.
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        while((state & (eNextFlipPending|eInvalidSurface)) ||
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	              (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	              ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        {
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            if (state & eInvalidSurface)
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	                return NO_MEMORY;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            if (!blocking)
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	                return WOULD_BLOCK;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                timeout = 0;
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                result = cv.waitRelative(lock, seconds(1));
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            if (__builtin_expect(result!=NO_ERROR, false)) {
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    const int newState = layer->swapState;
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    LOGW(   "lock_layer timed out (is the CPU pegged?) "
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            "layer=%d, lcblk=%p, state=%08x (was %08x)",
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            int(i), layer, newState, int(state));
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    timeout = newState != int(state);
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        start_loop_here:
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            state = layer->swapState;
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	            resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	        }
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            LOGW_IF(timeout,
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "lock_layer() timed out but didn't appear to need "
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "to be locked and we recovered "
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "(layer=%d, lcblk=%p, state=%08x)",
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int(i), layer, int(state));
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    }
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    // eFlipRequested is not set and cannot be set by another thread: it's
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    // safe to use the first buffer without synchronization.
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Choose the index depending on eFlipRequested.
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // When it's set, choose the 'other' buffer.
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    // make sure this buffer is valid
203076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        status_t err = layer->surface[index].status;
204076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian	    if (err < 0) {
205076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian	        return err;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    }
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (inspect) {
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we just want to inspect this layer. don't lock it.
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            goto done;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project	    // last thing before we're done, we need to atomically lock the state
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         int(i), layer, int(index), int(state));
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // store the index of the locked buffer (for client use only)
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->flags &= ~eBufferIndex;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectdone:
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return index;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
229076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // atomically set eFlipRequested and clear eLocked and optionally
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // set eNextFlipPending if eFlipRequested was already set
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_cblk_t * const layer = layers + i;
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int32_t oldvalue, newvalue;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    do {
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        oldvalue = layer->swapState;
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // get current value
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        newvalue = oldvalue & ~eLocked;
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // clear eLocked
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        newvalue |= eFlipRequested;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // set eFlipRequested
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (oldvalue & eFlipRequested)
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            newvalue |= eNextFlipPending;
246076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // if eFlipRequested was already set, set eNextFlipPending
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            int(newvalue));
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // from this point, the server can kick in at any time and use the first
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // buffer, so we cannot use it anymore, and we must use the 'other'
256076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // buffer instead (or wait if it is not available yet, see lock_layer).
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return newvalue;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid per_client_cblk_t::unlock_layer(size_t i)
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_cblk_t * const layer = layers + i;
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    android_atomic_and(~eLocked, &layer->swapState);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline int compare_type( const layer_state_t& lhs,
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                const layer_state_t& rhs) {
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (lhs.surface < rhs.surface)  return -1;
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (lhs.surface > rhs.surface)  return 1;
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return 0;
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceComposerClient::SurfaceComposerClient()
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<ISurfaceComposer>& sm(_get_surface_manager());
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (sm == 0) {
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        _init(0, 0);
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _init(sm, sm->createConnection());
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mClient != 0) {
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Mutex::Autolock _l(gLock);
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        VERBOSE("Adding client %p to map", this);
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gActiveConnections.add(mClient->asBinder(), this);
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceComposerClient::SurfaceComposerClient(
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceComposerClient::_init(
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("Creating client %p, conn %p", this, conn.get());
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSignalServer = 0;
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mPrebuiltLayerState = 0;
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransactionOpen = 0;
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mStatus = NO_ERROR;
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mControl = 0;
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mClient = conn;
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mClient == 0) {
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mStatus = NO_INIT;
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mClient->getControlBlocks(&mControlMemory);
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSignalServer = new SurfaceFlingerSynchro(sm);
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceComposerClient::~SurfaceComposerClient()
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("Destroying client %p, conn %p", this, mClient.get());
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dispose();
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::initCheck() const
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mStatus;
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IBinder> SurfaceComposerClient::connection() const
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (mClient != 0) ? mClient->asBinder() : 0;
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<SurfaceComposerClient>
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<SurfaceComposerClient> client;
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    { // scope for lock
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Mutex::Autolock _l(gLock);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        client = gActiveConnections.valueFor(conn);
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (client == 0) {
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Need to make a new client.
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurfaceComposer>& sm(_get_surface_manager());
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        client = new SurfaceComposerClient(sm, conn);
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (client != 0 && client->initCheck() == NO_ERROR) {
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            Mutex::Autolock _l(gLock);
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            gActiveConnections.add(conn, client);
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            //LOGD("we have %d connections", gActiveConnections.size());
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            client.clear();
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return client;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceComposerClient::dispose()
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // this can be called more than once.
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<IMemory>                 controlMemory;
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<ISurfaceFlingerClient>   client;
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Mutex::Autolock _lg(gLock);
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Mutex::Autolock _lm(mLock);
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        delete mSignalServer;
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mSignalServer = 0;
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mClient != 0) {
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            client = mClient;
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mClient.clear();
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (i >= 0 && gActiveConnections.valueAt(i) == this) {
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                VERBOSE("Removing client %p from map at %d", this, int(i));
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                gActiveConnections.removeItemsAt(i);
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        delete mPrebuiltLayerState;
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPrebuiltLayerState = 0;
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        controlMemory = mControlMemory;
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mControlMemory.clear();
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mControl = 0;
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mStatus = NO_INIT;
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::getDisplayInfo(
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID dpy, DisplayInfo* info)
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile surface_flinger_cblk_t const * cblk = get_cblk();
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->w              = dcblk->w;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->h              = dcblk->h;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->orientation    = dcblk->orientation;
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->xdpi           = dcblk->xdpi;
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->ydpi           = dcblk->ydpi;
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->fps            = dcblk->fps;
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    info->density        = dcblk->density;
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile surface_flinger_cblk_t const * cblk = get_cblk();
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return dcblk->w;
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile surface_flinger_cblk_t const * cblk = get_cblk();
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return dcblk->h;
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return BAD_VALUE;
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile surface_flinger_cblk_t const * cblk = get_cblk();
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return dcblk->orientation;
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t SurfaceComposerClient::getNumberOfDisplays()
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    volatile surface_flinger_cblk_t const * cblk = get_cblk();
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t connected = cblk->connected;
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int n = 0;
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (connected) {
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (connected&1) n++;
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        connected >>= 1;
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return n;
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid SurfaceComposerClient::signalServer()
457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mSignalServer->signal();
459076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
460076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<Surface> SurfaceComposerClient::createSurface(
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int pid,
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID display,
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t w,
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t h,
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        PixelFormat format,
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    sp<Surface> result;
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mStatus == NO_ERROR) {
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ISurfaceFlingerClient::surface_data_t data;
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<ISurface> surface = mClient->createSurface(&data, pid,
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                display, w, h, format, flags);
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (surface != 0) {
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (uint32_t(data.token) < NUM_LAYERS_MAX) {
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                result = new Surface(this, surface, data, w, h, format, flags);
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return result;
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::destroySurface(SurfaceID sid)
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mStatus != NO_ERROR)
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mStatus;
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // it's okay to destroy a surface while a transaction is open,
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // (transactions really are a client-side concept)
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // however, this indicates probably a misuse of the API or a bug
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // in the client code.
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGW_IF(mTransactionOpen,
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         "Destroying surface while a transaction is open. "
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         "Client %p: destroying surface %d, mTransactionOpen=%d",
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project         this, sid, mTransactionOpen);
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = mClient->destroySurface(sid);
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceComposerClient::openGlobalTransaction()
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(gLock);
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (gOpenTransactions.size()) {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("openGlobalTransaction() called more than once. skipping.");
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = gActiveConnections.size();
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("openGlobalTransaction (%ld clients)", N);
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (gOpenTransactions.indexOf(client) < 0) {
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (client->openTransaction() == NO_ERROR) {
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (gOpenTransactions.add(client) < 0) {
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // Ooops!
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    LOGE(   "Unable to add a SurfaceComposerClient "
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            "to the global transaction set (out of memory?)");
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    client->closeTransaction();
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // let it go, it'll fail later when the user
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // tries to do something with the transaction
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                LOGE("openTransaction on client %p failed", client.get());
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // let it go, it'll fail later when the user
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // tries to do something with the transaction
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceComposerClient::closeGlobalTransaction()
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gLock.lock();
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        gOpenTransactions.clear();
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gLock.unlock();
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = clients.size();
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE("closeGlobalTransaction (%ld clients)", N);
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (N == 1) {
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        clients[0]->closeTransaction();
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<ISurfaceComposer>& sm(_get_surface_manager());
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sm->openGlobalTransaction();
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0; i<N; i++) {
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            clients[i]->closeTransaction();
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        sm->closeGlobalTransaction();
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<ISurfaceComposer>& sm(_get_surface_manager());
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return sm->freezeDisplay(dpy, flags);
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<ISurfaceComposer>& sm(_get_surface_manager());
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return sm->unfreezeDisplay(dpy, flags);
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
566c08731e756868653d09d3e49b723706df3687070Mathias Agopianint SurfaceComposerClient::setOrientation(DisplayID dpy,
567c08731e756868653d09d3e49b723706df3687070Mathias Agopian        int orientation, uint32_t flags)
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const sp<ISurfaceComposer>& sm(_get_surface_manager());
570c08731e756868653d09d3e49b723706df3687070Mathias Agopian    return sm->setOrientation(dpy, orientation, flags);
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::openTransaction()
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mStatus != NO_ERROR)
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mStatus;
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            this, mTransactionOpen);
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransactionOpen++;
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mPrebuiltLayerState == 0) {
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mPrebuiltLayerState = new layer_state_t;
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::closeTransaction()
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mStatus != NO_ERROR)
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return mStatus;
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Mutex::Autolock _l(mLock);
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            this, mTransactionOpen);
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTransactionOpen <= 0) {
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "called more times than openTransaction()",
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                this, mTransactionOpen);
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return INVALID_OPERATION;
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTransactionOpen >= 2) {
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionOpen--;
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mTransactionOpen = 0;
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const ssize_t count = mStates.size();
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (count) {
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mClient->setState(count, mStates.array());
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mStates.clear();
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectlayer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SurfaceID index = surface->ID();
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    per_client_cblk_t* const cblk = mControl;
623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = surface->validate(cblk);
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err != NO_ERROR)
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // API usage error, do nothing.
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mTransactionOpen<=0) {
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                this, int(index), mTransactionOpen);
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return 0;
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // use mPrebuiltLayerState just to find out if we already have it
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t& dummy = *mPrebuiltLayerState;
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    dummy.surface = index;
637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t i = mStates.indexOf(dummy);
638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (i < 0) {
639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // we don't have it, add an initialized layer_state to our list
640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        i = mStates.add(dummy);
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mStates.editArray() + i;
643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectlayer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s;
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.lock();
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s = _get_state_l(surface);
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) mLock.unlock();
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return s;
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceComposerClient::_unlockLayerState()
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mLock.unlock();
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::ePositionChanged;
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->x = x;
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->y = y;
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eSizeChanged;
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->w = w;
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->h = h;
677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eLayerChanged;
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->z = z;
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::hide(Surface* surface)
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setFlags(surface, ISurfaceComposer::eLayerHidden,
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ISurfaceComposer::eLayerHidden);
695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::show(Surface* surface, int32_t)
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::freeze(Surface* surface)
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setFlags(surface, ISurfaceComposer::eLayerFrozen,
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ISurfaceComposer::eLayerFrozen);
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::unfreeze(Surface* surface)
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setFlags(Surface* surface,
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags, uint32_t mask)
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eVisibilityChanged;
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->flags &= ~mask;
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->flags |= (flags & mask);
721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->mask |= mask;
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setTransparentRegionHint(
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Surface* surface, const Region& transparentRegion)
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eTransparentRegionChanged;
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->transparentRegion = transparentRegion;
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eAlphaChanged;
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->alpha = alpha;
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setMatrix(
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Surface* surface,
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        float dsdx, float dtdx,
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        float dsdy, float dtdy )
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eMatrixChanged;
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t::matrix22_t matrix;
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    matrix.dsdx = dsdx;
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    matrix.dtdx = dtdx;
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    matrix.dsdy = dsdy;
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    matrix.dtdy = dtdy;
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->matrix = matrix;
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    layer_state_t* s = _lockLayerState(surface);
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (!s) return BAD_INDEX;
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->what |= ISurfaceComposer::eFreezeTintChanged;
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    s->tint = tint;
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    _unlockLayerState();
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
777