blob: 3baa2817aac4ba19f29acc672d75c8a2dd38ab22 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SurfaceComposerClient"
18
19#include <stdint.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25
26#include <cutils/memory.h>
27
28#include <utils/Atomic.h>
29#include <utils/Errors.h>
30#include <utils/threads.h>
31#include <utils/KeyedVector.h>
Mathias Agopian07952722009-05-19 19:08:10 -070032#include <binder/IServiceManager.h>
33#include <binder/IMemory.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034#include <utils/Log.h>
35
Mathias Agopian1473f462009-04-10 14:24:30 -070036#include <ui/DisplayInfo.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037#include <ui/ISurfaceComposer.h>
38#include <ui/ISurfaceFlingerClient.h>
39#include <ui/ISurface.h>
40#include <ui/SurfaceComposerClient.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041#include <ui/Rect.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043#include <private/ui/LayerState.h>
Mathias Agopian9779b222009-09-07 16:32:45 -070044#include <private/ui/SharedBufferStack.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045#include <private/ui/SurfaceFlingerSynchro.h>
46
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047#define VERBOSE(...) ((void)0)
48//#define VERBOSE LOGD
49
50#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
51#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
52
53namespace android {
54
55// ---------------------------------------------------------------------------
56
57// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
58static Mutex gLock;
59static sp<ISurfaceComposer> gSurfaceManager;
60static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
61static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
Mathias Agopiand763b5d2009-07-02 18:11:53 -070062static sp<IMemoryHeap> gServerCblkMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063static volatile surface_flinger_cblk_t* gServerCblk;
64
Mathias Agopianbc726112009-09-23 15:44:05 -070065static sp<ISurfaceComposer> getComposerService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066{
Mathias Agopianbc726112009-09-23 15:44:05 -070067 sp<ISurfaceComposer> sc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 Mutex::Autolock _l(gLock);
Mathias Agopianbc726112009-09-23 15:44:05 -070069 if (gSurfaceManager != 0) {
70 sc = gSurfaceManager;
71 } else {
72 // release the lock while we're waiting...
73 gLock.unlock();
74
75 sp<IBinder> binder;
76 sp<IServiceManager> sm = defaultServiceManager();
77 do {
78 binder = sm->getService(String16("SurfaceFlinger"));
79 if (binder == 0) {
80 LOGW("SurfaceFlinger not published, waiting...");
81 usleep(500000); // 0.5 s
82 }
83 } while(binder == 0);
84
85 // grab the lock again for updating gSurfaceManager
86 gLock.lock();
87 if (gSurfaceManager == 0) {
88 sc = interface_cast<ISurfaceComposer>(binder);
89 gSurfaceManager = sc;
90 } else {
91 sc = gSurfaceManager;
92 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
Mathias Agopianbc726112009-09-23 15:44:05 -070094 return sc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095}
96
97static volatile surface_flinger_cblk_t const * get_cblk()
98{
99 if (gServerCblk == 0) {
Mathias Agopianbc726112009-09-23 15:44:05 -0700100 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 Mutex::Autolock _l(gLock);
102 if (gServerCblk == 0) {
103 gServerCblkMemory = sm->getCblk();
104 LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700105 gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 LOGE_IF(gServerCblk==0, "Can't get server control block address");
107 }
108 }
109 return gServerCblk;
110}
111
112// ---------------------------------------------------------------------------
113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114static inline int compare_type( const layer_state_t& lhs,
115 const layer_state_t& rhs) {
116 if (lhs.surface < rhs.surface) return -1;
117 if (lhs.surface > rhs.surface) return 1;
118 return 0;
119}
120
121SurfaceComposerClient::SurfaceComposerClient()
122{
Mathias Agopianbc726112009-09-23 15:44:05 -0700123 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 if (sm == 0) {
125 _init(0, 0);
126 return;
127 }
128
129 _init(sm, sm->createConnection());
130
131 if (mClient != 0) {
132 Mutex::Autolock _l(gLock);
133 VERBOSE("Adding client %p to map", this);
134 gActiveConnections.add(mClient->asBinder(), this);
135 }
136}
137
138SurfaceComposerClient::SurfaceComposerClient(
139 const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
140{
141 _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
142}
143
Mathias Agopianbc726112009-09-23 15:44:05 -0700144
145status_t SurfaceComposerClient::linkToComposerDeath(
146 const sp<IBinder::DeathRecipient>& recipient,
147 void* cookie, uint32_t flags)
148{
149 sp<ISurfaceComposer> sm(getComposerService());
150 return sm->asBinder()->linkToDeath(recipient, cookie, flags);
151}
152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153void SurfaceComposerClient::_init(
154 const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
155{
156 VERBOSE("Creating client %p, conn %p", this, conn.get());
157
158 mSignalServer = 0;
159 mPrebuiltLayerState = 0;
160 mTransactionOpen = 0;
161 mStatus = NO_ERROR;
162 mControl = 0;
163
164 mClient = conn;
165 if (mClient == 0) {
166 mStatus = NO_INIT;
167 return;
168 }
169
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700170 mControlMemory = mClient->getControlBlock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 mSignalServer = new SurfaceFlingerSynchro(sm);
Mathias Agopian9779b222009-09-07 16:32:45 -0700172 mControl = static_cast<SharedClient *>(mControlMemory->getBase());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173}
174
175SurfaceComposerClient::~SurfaceComposerClient()
176{
177 VERBOSE("Destroying client %p, conn %p", this, mClient.get());
178 dispose();
179}
180
181status_t SurfaceComposerClient::initCheck() const
182{
183 return mStatus;
184}
185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186sp<IBinder> SurfaceComposerClient::connection() const
187{
188 return (mClient != 0) ? mClient->asBinder() : 0;
189}
190
191sp<SurfaceComposerClient>
192SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
193{
194 sp<SurfaceComposerClient> client;
195
196 { // scope for lock
197 Mutex::Autolock _l(gLock);
198 client = gActiveConnections.valueFor(conn);
199 }
200
201 if (client == 0) {
202 // Need to make a new client.
Mathias Agopianbc726112009-09-23 15:44:05 -0700203 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 client = new SurfaceComposerClient(sm, conn);
205 if (client != 0 && client->initCheck() == NO_ERROR) {
206 Mutex::Autolock _l(gLock);
207 gActiveConnections.add(conn, client);
208 //LOGD("we have %d connections", gActiveConnections.size());
209 } else {
210 client.clear();
211 }
212 }
213
214 return client;
215}
216
217void SurfaceComposerClient::dispose()
218{
219 // this can be called more than once.
220
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700221 sp<IMemoryHeap> controlMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 sp<ISurfaceFlingerClient> client;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223
224 {
225 Mutex::Autolock _lg(gLock);
226 Mutex::Autolock _lm(mLock);
227
228 delete mSignalServer;
229 mSignalServer = 0;
230
231 if (mClient != 0) {
232 client = mClient;
233 mClient.clear();
234
235 ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
236 if (i >= 0 && gActiveConnections.valueAt(i) == this) {
237 VERBOSE("Removing client %p from map at %d", this, int(i));
238 gActiveConnections.removeItemsAt(i);
239 }
240 }
241
242 delete mPrebuiltLayerState;
243 mPrebuiltLayerState = 0;
244 controlMemory = mControlMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 mControlMemory.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 mControl = 0;
247 mStatus = NO_INIT;
248 }
249}
250
251status_t SurfaceComposerClient::getDisplayInfo(
252 DisplayID dpy, DisplayInfo* info)
253{
254 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
255 return BAD_VALUE;
256
257 volatile surface_flinger_cblk_t const * cblk = get_cblk();
258 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
259
260 info->w = dcblk->w;
261 info->h = dcblk->h;
262 info->orientation = dcblk->orientation;
263 info->xdpi = dcblk->xdpi;
264 info->ydpi = dcblk->ydpi;
265 info->fps = dcblk->fps;
266 info->density = dcblk->density;
267 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
268}
269
270ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
271{
272 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
273 return BAD_VALUE;
274 volatile surface_flinger_cblk_t const * cblk = get_cblk();
275 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
276 return dcblk->w;
277}
278
279ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
280{
281 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
282 return BAD_VALUE;
283 volatile surface_flinger_cblk_t const * cblk = get_cblk();
284 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
285 return dcblk->h;
286}
287
288ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
289{
290 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
291 return BAD_VALUE;
292 volatile surface_flinger_cblk_t const * cblk = get_cblk();
293 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
294 return dcblk->orientation;
295}
296
297ssize_t SurfaceComposerClient::getNumberOfDisplays()
298{
299 volatile surface_flinger_cblk_t const * cblk = get_cblk();
300 uint32_t connected = cblk->connected;
301 int n = 0;
302 while (connected) {
303 if (connected&1) n++;
304 connected >>= 1;
305 }
306 return n;
307}
308
Mathias Agopian1473f462009-04-10 14:24:30 -0700309
310void SurfaceComposerClient::signalServer()
311{
312 mSignalServer->signal();
313}
314
Mathias Agopian17f638b2009-04-16 20:04:08 -0700315sp<SurfaceControl> SurfaceComposerClient::createSurface(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 int pid,
317 DisplayID display,
318 uint32_t w,
319 uint32_t h,
320 PixelFormat format,
321 uint32_t flags)
322{
Mathias Agopian17f638b2009-04-16 20:04:08 -0700323 sp<SurfaceControl> result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 if (mStatus == NO_ERROR) {
325 ISurfaceFlingerClient::surface_data_t data;
326 sp<ISurface> surface = mClient->createSurface(&data, pid,
327 display, w, h, format, flags);
328 if (surface != 0) {
329 if (uint32_t(data.token) < NUM_LAYERS_MAX) {
Mathias Agopian17f638b2009-04-16 20:04:08 -0700330 result = new SurfaceControl(this, surface, data, w, h, format, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332 }
333 }
334 return result;
335}
336
337status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
338{
339 if (mStatus != NO_ERROR)
340 return mStatus;
341
342 // it's okay to destroy a surface while a transaction is open,
343 // (transactions really are a client-side concept)
344 // however, this indicates probably a misuse of the API or a bug
345 // in the client code.
346 LOGW_IF(mTransactionOpen,
347 "Destroying surface while a transaction is open. "
348 "Client %p: destroying surface %d, mTransactionOpen=%d",
349 this, sid, mTransactionOpen);
350
351 status_t err = mClient->destroySurface(sid);
352 return err;
353}
354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355void SurfaceComposerClient::openGlobalTransaction()
356{
357 Mutex::Autolock _l(gLock);
358
359 if (gOpenTransactions.size()) {
360 LOGE("openGlobalTransaction() called more than once. skipping.");
361 return;
362 }
363
364 const size_t N = gActiveConnections.size();
365 VERBOSE("openGlobalTransaction (%ld clients)", N);
366 for (size_t i=0; i<N; i++) {
367 sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
368 if (gOpenTransactions.indexOf(client) < 0) {
369 if (client->openTransaction() == NO_ERROR) {
370 if (gOpenTransactions.add(client) < 0) {
371 // Ooops!
372 LOGE( "Unable to add a SurfaceComposerClient "
373 "to the global transaction set (out of memory?)");
374 client->closeTransaction();
375 // let it go, it'll fail later when the user
376 // tries to do something with the transaction
377 }
378 } else {
379 LOGE("openTransaction on client %p failed", client.get());
380 // let it go, it'll fail later when the user
381 // tries to do something with the transaction
382 }
383 }
384 }
385}
386
387void SurfaceComposerClient::closeGlobalTransaction()
388{
389 gLock.lock();
390 SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
391 gOpenTransactions.clear();
392 gLock.unlock();
393
394 const size_t N = clients.size();
395 VERBOSE("closeGlobalTransaction (%ld clients)", N);
Mathias Agopian9779b222009-09-07 16:32:45 -0700396
Mathias Agopianbc726112009-09-23 15:44:05 -0700397 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopian9779b222009-09-07 16:32:45 -0700398 sm->openGlobalTransaction();
399 for (size_t i=0; i<N; i++) {
400 clients[i]->closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 }
Mathias Agopian9779b222009-09-07 16:32:45 -0700402 sm->closeGlobalTransaction();
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404}
405
Mathias Agopian9779b222009-09-07 16:32:45 -0700406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
408{
Mathias Agopianbc726112009-09-23 15:44:05 -0700409 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 return sm->freezeDisplay(dpy, flags);
411}
412
413status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
414{
Mathias Agopianbc726112009-09-23 15:44:05 -0700415 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 return sm->unfreezeDisplay(dpy, flags);
417}
418
Mathias Agopianeb0c86e2009-03-27 18:11:38 -0700419int SurfaceComposerClient::setOrientation(DisplayID dpy,
420 int orientation, uint32_t flags)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421{
Mathias Agopianbc726112009-09-23 15:44:05 -0700422 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopianeb0c86e2009-03-27 18:11:38 -0700423 return sm->setOrientation(dpy, orientation, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424}
425
426status_t SurfaceComposerClient::openTransaction()
427{
428 if (mStatus != NO_ERROR)
429 return mStatus;
430 Mutex::Autolock _l(mLock);
431 VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
432 this, mTransactionOpen);
433 mTransactionOpen++;
434 if (mPrebuiltLayerState == 0) {
435 mPrebuiltLayerState = new layer_state_t;
436 }
437 return NO_ERROR;
438}
439
440
441status_t SurfaceComposerClient::closeTransaction()
442{
443 if (mStatus != NO_ERROR)
444 return mStatus;
445
446 Mutex::Autolock _l(mLock);
447
448 VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
449 this, mTransactionOpen);
450
451 if (mTransactionOpen <= 0) {
452 LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
453 "called more times than openTransaction()",
454 this, mTransactionOpen);
455 return INVALID_OPERATION;
456 }
457
458 if (mTransactionOpen >= 2) {
459 mTransactionOpen--;
460 return NO_ERROR;
461 }
462
463 mTransactionOpen = 0;
464 const ssize_t count = mStates.size();
465 if (count) {
466 mClient->setState(count, mStates.array());
467 mStates.clear();
468 }
469 return NO_ERROR;
470}
471
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700472layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 // API usage error, do nothing.
475 if (mTransactionOpen<=0) {
476 LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
477 this, int(index), mTransactionOpen);
478 return 0;
479 }
480
481 // use mPrebuiltLayerState just to find out if we already have it
482 layer_state_t& dummy = *mPrebuiltLayerState;
483 dummy.surface = index;
484 ssize_t i = mStates.indexOf(dummy);
485 if (i < 0) {
486 // we don't have it, add an initialized layer_state to our list
487 i = mStates.add(dummy);
488 }
489 return mStates.editArray() + i;
490}
491
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700492layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493{
494 layer_state_t* s;
495 mLock.lock();
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700496 s = _get_state_l(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 if (!s) mLock.unlock();
498 return s;
499}
500
501void SurfaceComposerClient::_unlockLayerState()
502{
503 mLock.unlock();
504}
505
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700506status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700508 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 if (!s) return BAD_INDEX;
510 s->what |= ISurfaceComposer::ePositionChanged;
511 s->x = x;
512 s->y = y;
513 _unlockLayerState();
514 return NO_ERROR;
515}
516
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700517status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700519 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 if (!s) return BAD_INDEX;
521 s->what |= ISurfaceComposer::eSizeChanged;
522 s->w = w;
523 s->h = h;
524 _unlockLayerState();
525 return NO_ERROR;
526}
527
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700528status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700530 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 if (!s) return BAD_INDEX;
532 s->what |= ISurfaceComposer::eLayerChanged;
533 s->z = z;
534 _unlockLayerState();
535 return NO_ERROR;
536}
537
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700538status_t SurfaceComposerClient::hide(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700540 return setFlags(id, ISurfaceComposer::eLayerHidden,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 ISurfaceComposer::eLayerHidden);
542}
543
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700544status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700546 return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547}
548
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700549status_t SurfaceComposerClient::freeze(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700551 return setFlags(id, ISurfaceComposer::eLayerFrozen,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 ISurfaceComposer::eLayerFrozen);
553}
554
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700555status_t SurfaceComposerClient::unfreeze(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700557 return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558}
559
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700560status_t SurfaceComposerClient::setFlags(SurfaceID id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 uint32_t flags, uint32_t mask)
562{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700563 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 if (!s) return BAD_INDEX;
565 s->what |= ISurfaceComposer::eVisibilityChanged;
566 s->flags &= ~mask;
567 s->flags |= (flags & mask);
568 s->mask |= mask;
569 _unlockLayerState();
570 return NO_ERROR;
571}
572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573status_t SurfaceComposerClient::setTransparentRegionHint(
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700574 SurfaceID id, const Region& transparentRegion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700576 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 if (!s) return BAD_INDEX;
578 s->what |= ISurfaceComposer::eTransparentRegionChanged;
579 s->transparentRegion = transparentRegion;
580 _unlockLayerState();
581 return NO_ERROR;
582}
583
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700584status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700586 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 if (!s) return BAD_INDEX;
588 s->what |= ISurfaceComposer::eAlphaChanged;
589 s->alpha = alpha;
590 _unlockLayerState();
591 return NO_ERROR;
592}
593
594status_t SurfaceComposerClient::setMatrix(
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700595 SurfaceID id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 float dsdx, float dtdx,
597 float dsdy, float dtdy )
598{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700599 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 if (!s) return BAD_INDEX;
601 s->what |= ISurfaceComposer::eMatrixChanged;
602 layer_state_t::matrix22_t matrix;
603 matrix.dsdx = dsdx;
604 matrix.dtdx = dtdx;
605 matrix.dsdy = dsdy;
606 matrix.dtdy = dtdy;
607 s->matrix = matrix;
608 _unlockLayerState();
609 return NO_ERROR;
610}
611
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700612status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700614 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 if (!s) return BAD_INDEX;
616 s->what |= ISurfaceComposer::eFreezeTintChanged;
617 s->tint = tint;
618 _unlockLayerState();
619 return NO_ERROR;
620}
621
622}; // namespace android
623