blob: eda84eff04f428dfdeb393c440c6764ca1d265f1 [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046#define VERBOSE(...) ((void)0)
47//#define VERBOSE LOGD
48
49#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
50#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
51
52namespace android {
53
54// ---------------------------------------------------------------------------
55
56// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
57static Mutex gLock;
58static sp<ISurfaceComposer> gSurfaceManager;
59static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
60static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
Mathias Agopiand763b5d2009-07-02 18:11:53 -070061static sp<IMemoryHeap> gServerCblkMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062static volatile surface_flinger_cblk_t* gServerCblk;
63
Mathias Agopianbc726112009-09-23 15:44:05 -070064static sp<ISurfaceComposer> getComposerService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065{
Mathias Agopianbc726112009-09-23 15:44:05 -070066 sp<ISurfaceComposer> sc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 Mutex::Autolock _l(gLock);
Mathias Agopianbc726112009-09-23 15:44:05 -070068 if (gSurfaceManager != 0) {
69 sc = gSurfaceManager;
70 } else {
71 // release the lock while we're waiting...
72 gLock.unlock();
73
74 sp<IBinder> binder;
75 sp<IServiceManager> sm = defaultServiceManager();
76 do {
77 binder = sm->getService(String16("SurfaceFlinger"));
78 if (binder == 0) {
79 LOGW("SurfaceFlinger not published, waiting...");
80 usleep(500000); // 0.5 s
81 }
82 } while(binder == 0);
83
84 // grab the lock again for updating gSurfaceManager
85 gLock.lock();
86 if (gSurfaceManager == 0) {
87 sc = interface_cast<ISurfaceComposer>(binder);
88 gSurfaceManager = sc;
89 } else {
90 sc = gSurfaceManager;
91 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 }
Mathias Agopianbc726112009-09-23 15:44:05 -070093 return sc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094}
95
96static volatile surface_flinger_cblk_t const * get_cblk()
97{
98 if (gServerCblk == 0) {
Mathias Agopianbc726112009-09-23 15:44:05 -070099 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 Mutex::Autolock _l(gLock);
101 if (gServerCblk == 0) {
102 gServerCblkMemory = sm->getCblk();
103 LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700104 gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 LOGE_IF(gServerCblk==0, "Can't get server control block address");
106 }
107 }
108 return gServerCblk;
109}
110
111// ---------------------------------------------------------------------------
112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113static inline int compare_type( const layer_state_t& lhs,
114 const layer_state_t& rhs) {
115 if (lhs.surface < rhs.surface) return -1;
116 if (lhs.surface > rhs.surface) return 1;
117 return 0;
118}
119
120SurfaceComposerClient::SurfaceComposerClient()
121{
Mathias Agopianbc726112009-09-23 15:44:05 -0700122 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 if (sm == 0) {
124 _init(0, 0);
125 return;
126 }
127
128 _init(sm, sm->createConnection());
129
130 if (mClient != 0) {
131 Mutex::Autolock _l(gLock);
132 VERBOSE("Adding client %p to map", this);
133 gActiveConnections.add(mClient->asBinder(), this);
134 }
135}
136
137SurfaceComposerClient::SurfaceComposerClient(
138 const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
139{
140 _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
141}
142
Mathias Agopianbc726112009-09-23 15:44:05 -0700143
144status_t SurfaceComposerClient::linkToComposerDeath(
145 const sp<IBinder::DeathRecipient>& recipient,
146 void* cookie, uint32_t flags)
147{
148 sp<ISurfaceComposer> sm(getComposerService());
149 return sm->asBinder()->linkToDeath(recipient, cookie, flags);
150}
151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152void SurfaceComposerClient::_init(
153 const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
154{
155 VERBOSE("Creating client %p, conn %p", this, conn.get());
156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 mPrebuiltLayerState = 0;
158 mTransactionOpen = 0;
159 mStatus = NO_ERROR;
160 mControl = 0;
161
162 mClient = conn;
163 if (mClient == 0) {
164 mStatus = NO_INIT;
165 return;
166 }
167
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700168 mControlMemory = mClient->getControlBlock();
Mathias Agopiane05f07d2009-10-07 16:44:10 -0700169 mSignalServer = sm;
Mathias Agopian9779b222009-09-07 16:32:45 -0700170 mControl = static_cast<SharedClient *>(mControlMemory->getBase());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171}
172
173SurfaceComposerClient::~SurfaceComposerClient()
174{
175 VERBOSE("Destroying client %p, conn %p", this, mClient.get());
176 dispose();
177}
178
179status_t SurfaceComposerClient::initCheck() const
180{
181 return mStatus;
182}
183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184sp<IBinder> SurfaceComposerClient::connection() const
185{
186 return (mClient != 0) ? mClient->asBinder() : 0;
187}
188
189sp<SurfaceComposerClient>
190SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
191{
192 sp<SurfaceComposerClient> client;
193
194 { // scope for lock
195 Mutex::Autolock _l(gLock);
196 client = gActiveConnections.valueFor(conn);
197 }
198
199 if (client == 0) {
200 // Need to make a new client.
Mathias Agopianbc726112009-09-23 15:44:05 -0700201 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 client = new SurfaceComposerClient(sm, conn);
203 if (client != 0 && client->initCheck() == NO_ERROR) {
204 Mutex::Autolock _l(gLock);
205 gActiveConnections.add(conn, client);
206 //LOGD("we have %d connections", gActiveConnections.size());
207 } else {
208 client.clear();
209 }
210 }
211
212 return client;
213}
214
215void SurfaceComposerClient::dispose()
216{
217 // this can be called more than once.
218
Mathias Agopiand763b5d2009-07-02 18:11:53 -0700219 sp<IMemoryHeap> controlMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 sp<ISurfaceFlingerClient> client;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 {
223 Mutex::Autolock _lg(gLock);
224 Mutex::Autolock _lm(mLock);
225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 mSignalServer = 0;
227
228 if (mClient != 0) {
229 client = mClient;
230 mClient.clear();
231
232 ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
233 if (i >= 0 && gActiveConnections.valueAt(i) == this) {
234 VERBOSE("Removing client %p from map at %d", this, int(i));
235 gActiveConnections.removeItemsAt(i);
236 }
237 }
238
239 delete mPrebuiltLayerState;
240 mPrebuiltLayerState = 0;
241 controlMemory = mControlMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 mControlMemory.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 mControl = 0;
244 mStatus = NO_INIT;
245 }
246}
247
248status_t SurfaceComposerClient::getDisplayInfo(
249 DisplayID dpy, DisplayInfo* info)
250{
251 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
252 return BAD_VALUE;
253
254 volatile surface_flinger_cblk_t const * cblk = get_cblk();
255 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
256
257 info->w = dcblk->w;
258 info->h = dcblk->h;
259 info->orientation = dcblk->orientation;
260 info->xdpi = dcblk->xdpi;
261 info->ydpi = dcblk->ydpi;
262 info->fps = dcblk->fps;
263 info->density = dcblk->density;
264 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
265}
266
267ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
268{
269 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
270 return BAD_VALUE;
271 volatile surface_flinger_cblk_t const * cblk = get_cblk();
272 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
273 return dcblk->w;
274}
275
276ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
277{
278 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
279 return BAD_VALUE;
280 volatile surface_flinger_cblk_t const * cblk = get_cblk();
281 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
282 return dcblk->h;
283}
284
285ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
286{
287 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
288 return BAD_VALUE;
289 volatile surface_flinger_cblk_t const * cblk = get_cblk();
290 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
291 return dcblk->orientation;
292}
293
294ssize_t SurfaceComposerClient::getNumberOfDisplays()
295{
296 volatile surface_flinger_cblk_t const * cblk = get_cblk();
297 uint32_t connected = cblk->connected;
298 int n = 0;
299 while (connected) {
300 if (connected&1) n++;
301 connected >>= 1;
302 }
303 return n;
304}
305
Mathias Agopian1473f462009-04-10 14:24:30 -0700306
307void SurfaceComposerClient::signalServer()
308{
309 mSignalServer->signal();
310}
311
Mathias Agopian17f638b2009-04-16 20:04:08 -0700312sp<SurfaceControl> SurfaceComposerClient::createSurface(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 int pid,
314 DisplayID display,
315 uint32_t w,
316 uint32_t h,
317 PixelFormat format,
318 uint32_t flags)
319{
Mathias Agopian17f638b2009-04-16 20:04:08 -0700320 sp<SurfaceControl> result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 if (mStatus == NO_ERROR) {
322 ISurfaceFlingerClient::surface_data_t data;
323 sp<ISurface> surface = mClient->createSurface(&data, pid,
324 display, w, h, format, flags);
325 if (surface != 0) {
326 if (uint32_t(data.token) < NUM_LAYERS_MAX) {
Mathias Agopian17f638b2009-04-16 20:04:08 -0700327 result = new SurfaceControl(this, surface, data, w, h, format, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 }
329 }
330 }
331 return result;
332}
333
334status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
335{
336 if (mStatus != NO_ERROR)
337 return mStatus;
338
339 // it's okay to destroy a surface while a transaction is open,
340 // (transactions really are a client-side concept)
341 // however, this indicates probably a misuse of the API or a bug
342 // in the client code.
343 LOGW_IF(mTransactionOpen,
344 "Destroying surface while a transaction is open. "
345 "Client %p: destroying surface %d, mTransactionOpen=%d",
346 this, sid, mTransactionOpen);
347
348 status_t err = mClient->destroySurface(sid);
349 return err;
350}
351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352void SurfaceComposerClient::openGlobalTransaction()
353{
354 Mutex::Autolock _l(gLock);
355
356 if (gOpenTransactions.size()) {
357 LOGE("openGlobalTransaction() called more than once. skipping.");
358 return;
359 }
360
361 const size_t N = gActiveConnections.size();
362 VERBOSE("openGlobalTransaction (%ld clients)", N);
363 for (size_t i=0; i<N; i++) {
364 sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
365 if (gOpenTransactions.indexOf(client) < 0) {
366 if (client->openTransaction() == NO_ERROR) {
367 if (gOpenTransactions.add(client) < 0) {
368 // Ooops!
369 LOGE( "Unable to add a SurfaceComposerClient "
370 "to the global transaction set (out of memory?)");
371 client->closeTransaction();
372 // let it go, it'll fail later when the user
373 // tries to do something with the transaction
374 }
375 } else {
376 LOGE("openTransaction on client %p failed", client.get());
377 // let it go, it'll fail later when the user
378 // tries to do something with the transaction
379 }
380 }
381 }
382}
383
384void SurfaceComposerClient::closeGlobalTransaction()
385{
386 gLock.lock();
387 SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
388 gOpenTransactions.clear();
389 gLock.unlock();
390
391 const size_t N = clients.size();
392 VERBOSE("closeGlobalTransaction (%ld clients)", N);
Mathias Agopian9779b222009-09-07 16:32:45 -0700393
Mathias Agopianbc726112009-09-23 15:44:05 -0700394 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopian9779b222009-09-07 16:32:45 -0700395 sm->openGlobalTransaction();
396 for (size_t i=0; i<N; i++) {
397 clients[i]->closeTransaction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 }
Mathias Agopian9779b222009-09-07 16:32:45 -0700399 sm->closeGlobalTransaction();
400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401}
402
Mathias Agopian9779b222009-09-07 16:32:45 -0700403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
405{
Mathias Agopianbc726112009-09-23 15:44:05 -0700406 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 return sm->freezeDisplay(dpy, flags);
408}
409
410status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
411{
Mathias Agopianbc726112009-09-23 15:44:05 -0700412 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 return sm->unfreezeDisplay(dpy, flags);
414}
415
Mathias Agopianeb0c86e2009-03-27 18:11:38 -0700416int SurfaceComposerClient::setOrientation(DisplayID dpy,
417 int orientation, uint32_t flags)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418{
Mathias Agopianbc726112009-09-23 15:44:05 -0700419 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopianeb0c86e2009-03-27 18:11:38 -0700420 return sm->setOrientation(dpy, orientation, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421}
422
423status_t SurfaceComposerClient::openTransaction()
424{
425 if (mStatus != NO_ERROR)
426 return mStatus;
427 Mutex::Autolock _l(mLock);
428 VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
429 this, mTransactionOpen);
430 mTransactionOpen++;
431 if (mPrebuiltLayerState == 0) {
432 mPrebuiltLayerState = new layer_state_t;
433 }
434 return NO_ERROR;
435}
436
437
438status_t SurfaceComposerClient::closeTransaction()
439{
440 if (mStatus != NO_ERROR)
441 return mStatus;
442
443 Mutex::Autolock _l(mLock);
444
445 VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
446 this, mTransactionOpen);
447
448 if (mTransactionOpen <= 0) {
449 LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
450 "called more times than openTransaction()",
451 this, mTransactionOpen);
452 return INVALID_OPERATION;
453 }
454
455 if (mTransactionOpen >= 2) {
456 mTransactionOpen--;
457 return NO_ERROR;
458 }
459
460 mTransactionOpen = 0;
461 const ssize_t count = mStates.size();
462 if (count) {
463 mClient->setState(count, mStates.array());
464 mStates.clear();
465 }
466 return NO_ERROR;
467}
468
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700469layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 // API usage error, do nothing.
472 if (mTransactionOpen<=0) {
473 LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
474 this, int(index), mTransactionOpen);
475 return 0;
476 }
477
478 // use mPrebuiltLayerState just to find out if we already have it
479 layer_state_t& dummy = *mPrebuiltLayerState;
480 dummy.surface = index;
481 ssize_t i = mStates.indexOf(dummy);
482 if (i < 0) {
483 // we don't have it, add an initialized layer_state to our list
484 i = mStates.add(dummy);
485 }
486 return mStates.editArray() + i;
487}
488
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700489layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490{
491 layer_state_t* s;
492 mLock.lock();
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700493 s = _get_state_l(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 if (!s) mLock.unlock();
495 return s;
496}
497
498void SurfaceComposerClient::_unlockLayerState()
499{
500 mLock.unlock();
501}
502
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700503status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700505 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 if (!s) return BAD_INDEX;
507 s->what |= ISurfaceComposer::ePositionChanged;
508 s->x = x;
509 s->y = y;
510 _unlockLayerState();
511 return NO_ERROR;
512}
513
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700514status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700516 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 if (!s) return BAD_INDEX;
518 s->what |= ISurfaceComposer::eSizeChanged;
519 s->w = w;
520 s->h = h;
521 _unlockLayerState();
522 return NO_ERROR;
523}
524
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700525status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700527 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 if (!s) return BAD_INDEX;
529 s->what |= ISurfaceComposer::eLayerChanged;
530 s->z = z;
531 _unlockLayerState();
532 return NO_ERROR;
533}
534
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700535status_t SurfaceComposerClient::hide(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700537 return setFlags(id, ISurfaceComposer::eLayerHidden,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 ISurfaceComposer::eLayerHidden);
539}
540
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700541status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700543 return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544}
545
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700546status_t SurfaceComposerClient::freeze(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700548 return setFlags(id, ISurfaceComposer::eLayerFrozen,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 ISurfaceComposer::eLayerFrozen);
550}
551
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700552status_t SurfaceComposerClient::unfreeze(SurfaceID id)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700554 return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555}
556
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700557status_t SurfaceComposerClient::setFlags(SurfaceID id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 uint32_t flags, uint32_t mask)
559{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700560 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 if (!s) return BAD_INDEX;
562 s->what |= ISurfaceComposer::eVisibilityChanged;
563 s->flags &= ~mask;
564 s->flags |= (flags & mask);
565 s->mask |= mask;
566 _unlockLayerState();
567 return NO_ERROR;
568}
569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570status_t SurfaceComposerClient::setTransparentRegionHint(
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700571 SurfaceID id, const Region& transparentRegion)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700573 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 if (!s) return BAD_INDEX;
575 s->what |= ISurfaceComposer::eTransparentRegionChanged;
576 s->transparentRegion = transparentRegion;
577 _unlockLayerState();
578 return NO_ERROR;
579}
580
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700581status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700583 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 if (!s) return BAD_INDEX;
585 s->what |= ISurfaceComposer::eAlphaChanged;
586 s->alpha = alpha;
587 _unlockLayerState();
588 return NO_ERROR;
589}
590
591status_t SurfaceComposerClient::setMatrix(
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700592 SurfaceID id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 float dsdx, float dtdx,
594 float dsdy, float dtdy )
595{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700596 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 if (!s) return BAD_INDEX;
598 s->what |= ISurfaceComposer::eMatrixChanged;
599 layer_state_t::matrix22_t matrix;
600 matrix.dsdx = dsdx;
601 matrix.dtdx = dtdx;
602 matrix.dsdy = dsdy;
603 matrix.dtdy = dtdy;
604 s->matrix = matrix;
605 _unlockLayerState();
606 return NO_ERROR;
607}
608
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700609status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610{
Mathias Agopian6d2c0bc2009-04-16 16:19:50 -0700611 layer_state_t* s = _lockLayerState(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 if (!s) return BAD_INDEX;
613 s->what |= ISurfaceComposer::eFreezeTintChanged;
614 s->tint = tint;
615 _unlockLayerState();
616 return NO_ERROR;
617}
618
619}; // namespace android
620