blob: 96ed5661b49ddb4d5b5dfab8dd75babfa189a732 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-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>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080032#include <utils/Log.h>
33
Mathias Agopian9cce3252010-02-09 17:46:37 -080034#include <binder/IServiceManager.h>
35#include <binder/IMemory.h>
36
Mathias Agopian076b1cc2009-04-10 14:24:30 -070037#include <ui/DisplayInfo.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038#include <ui/Rect.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039
Mathias Agopian9cce3252010-02-09 17:46:37 -080040#include <surfaceflinger/ISurfaceComposer.h>
41#include <surfaceflinger/ISurfaceFlingerClient.h>
42#include <surfaceflinger/ISurface.h>
43#include <surfaceflinger/SurfaceComposerClient.h>
44
45#include <private/surfaceflinger/LayerState.h>
46#include <private/surfaceflinger/SharedBufferStack.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080047
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080048#define VERBOSE(...) ((void)0)
49//#define VERBOSE LOGD
50
51#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
52#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
53
54namespace android {
55
56// ---------------------------------------------------------------------------
57
58// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
59static Mutex gLock;
60static sp<ISurfaceComposer> gSurfaceManager;
Matt Fischer166bcf92010-02-22 17:40:46 -060061static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080062static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
Mathias Agopian7303c6b2009-07-02 18:11:53 -070063static sp<IMemoryHeap> gServerCblkMemory;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080064static volatile surface_flinger_cblk_t* gServerCblk;
65
Mathias Agopiandd3423c2009-09-23 15:44:05 -070066static sp<ISurfaceComposer> getComposerService()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080067{
Mathias Agopiandd3423c2009-09-23 15:44:05 -070068 sp<ISurfaceComposer> sc;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080069 Mutex::Autolock _l(gLock);
Mathias Agopiandd3423c2009-09-23 15:44:05 -070070 if (gSurfaceManager != 0) {
71 sc = gSurfaceManager;
72 } else {
73 // release the lock while we're waiting...
74 gLock.unlock();
75
76 sp<IBinder> binder;
77 sp<IServiceManager> sm = defaultServiceManager();
78 do {
79 binder = sm->getService(String16("SurfaceFlinger"));
80 if (binder == 0) {
81 LOGW("SurfaceFlinger not published, waiting...");
82 usleep(500000); // 0.5 s
83 }
84 } while(binder == 0);
85
86 // grab the lock again for updating gSurfaceManager
87 gLock.lock();
88 if (gSurfaceManager == 0) {
89 sc = interface_cast<ISurfaceComposer>(binder);
90 gSurfaceManager = sc;
91 } else {
92 sc = gSurfaceManager;
93 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080094 }
Mathias Agopiandd3423c2009-09-23 15:44:05 -070095 return sc;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080096}
97
98static volatile surface_flinger_cblk_t const * get_cblk()
99{
100 if (gServerCblk == 0) {
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700101 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800102 Mutex::Autolock _l(gLock);
103 if (gServerCblk == 0) {
104 gServerCblkMemory = sm->getCblk();
105 LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
Mathias Agopian7303c6b2009-07-02 18:11:53 -0700106 gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800107 LOGE_IF(gServerCblk==0, "Can't get server control block address");
108 }
109 }
110 return gServerCblk;
111}
112
113// ---------------------------------------------------------------------------
114
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800115static inline int compare_type( const layer_state_t& lhs,
116 const layer_state_t& rhs) {
117 if (lhs.surface < rhs.surface) return -1;
118 if (lhs.surface > rhs.surface) return 1;
119 return 0;
120}
121
122SurfaceComposerClient::SurfaceComposerClient()
123{
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700124 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800125 if (sm == 0) {
Mathias Agopian631f3582010-05-25 17:51:34 -0700126 init(0, 0);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800127 return;
128 }
129
Mathias Agopian631f3582010-05-25 17:51:34 -0700130 init(sm, sm->createConnection());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800131
132 if (mClient != 0) {
133 Mutex::Autolock _l(gLock);
134 VERBOSE("Adding client %p to map", this);
135 gActiveConnections.add(mClient->asBinder(), this);
136 }
137}
138
139SurfaceComposerClient::SurfaceComposerClient(
140 const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
141{
Mathias Agopian631f3582010-05-25 17:51:34 -0700142 init(sm, interface_cast<ISurfaceFlingerClient>(conn));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800143}
144
Mathias Agopian631f3582010-05-25 17:51:34 -0700145SurfaceComposerClient::~SurfaceComposerClient()
146{
147 VERBOSE("Destroying client %p, conn %p", this, mClient.get());
148 dispose();
149}
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700150
151status_t SurfaceComposerClient::linkToComposerDeath(
152 const sp<IBinder::DeathRecipient>& recipient,
153 void* cookie, uint32_t flags)
154{
155 sp<ISurfaceComposer> sm(getComposerService());
156 return sm->asBinder()->linkToDeath(recipient, cookie, flags);
157}
158
Mathias Agopian631f3582010-05-25 17:51:34 -0700159void SurfaceComposerClient::init(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800160 const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
161{
162 VERBOSE("Creating client %p, conn %p", this, conn.get());
163
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800164 mPrebuiltLayerState = 0;
165 mTransactionOpen = 0;
166 mStatus = NO_ERROR;
167 mControl = 0;
168
169 mClient = conn;
170 if (mClient == 0) {
171 mStatus = NO_INIT;
172 return;
173 }
174
Mathias Agopian7303c6b2009-07-02 18:11:53 -0700175 mControlMemory = mClient->getControlBlock();
Mathias Agopiane7005012009-10-07 16:44:10 -0700176 mSignalServer = sm;
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700177 mControl = static_cast<SharedClient *>(mControlMemory->getBase());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800178}
179
Mathias Agopian631f3582010-05-25 17:51:34 -0700180SharedClient* SurfaceComposerClient::getSharedClient() const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800181{
Mathias Agopian631f3582010-05-25 17:51:34 -0700182 return mControl;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800183}
184
185status_t SurfaceComposerClient::initCheck() const
186{
187 return mStatus;
188}
189
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800190sp<IBinder> SurfaceComposerClient::connection() const
191{
192 return (mClient != 0) ? mClient->asBinder() : 0;
193}
194
195sp<SurfaceComposerClient>
196SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
197{
198 sp<SurfaceComposerClient> client;
199
200 { // scope for lock
201 Mutex::Autolock _l(gLock);
Matt Fischer166bcf92010-02-22 17:40:46 -0600202 client = gActiveConnections.valueFor(conn).promote();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203 }
204
205 if (client == 0) {
206 // Need to make a new client.
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700207 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800208 client = new SurfaceComposerClient(sm, conn);
209 if (client != 0 && client->initCheck() == NO_ERROR) {
210 Mutex::Autolock _l(gLock);
211 gActiveConnections.add(conn, client);
212 //LOGD("we have %d connections", gActiveConnections.size());
213 } else {
214 client.clear();
215 }
216 }
217
218 return client;
219}
220
221void SurfaceComposerClient::dispose()
222{
223 // this can be called more than once.
224
Mathias Agopian7303c6b2009-07-02 18:11:53 -0700225 sp<IMemoryHeap> controlMemory;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800226 sp<ISurfaceFlingerClient> client;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800227
228 {
229 Mutex::Autolock _lg(gLock);
230 Mutex::Autolock _lm(mLock);
231
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800232 mSignalServer = 0;
233
234 if (mClient != 0) {
235 client = mClient;
236 mClient.clear();
237
238 ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
239 if (i >= 0 && gActiveConnections.valueAt(i) == this) {
240 VERBOSE("Removing client %p from map at %d", this, int(i));
241 gActiveConnections.removeItemsAt(i);
242 }
243 }
244
245 delete mPrebuiltLayerState;
246 mPrebuiltLayerState = 0;
247 controlMemory = mControlMemory;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800248 mControlMemory.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800249 mControl = 0;
250 mStatus = NO_INIT;
251 }
252}
253
254status_t SurfaceComposerClient::getDisplayInfo(
255 DisplayID dpy, DisplayInfo* info)
256{
Mathias Agopianbb641242010-05-18 17:06:55 -0700257 if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800258 return BAD_VALUE;
259
260 volatile surface_flinger_cblk_t const * cblk = get_cblk();
261 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
262
263 info->w = dcblk->w;
264 info->h = dcblk->h;
265 info->orientation = dcblk->orientation;
266 info->xdpi = dcblk->xdpi;
267 info->ydpi = dcblk->ydpi;
268 info->fps = dcblk->fps;
269 info->density = dcblk->density;
270 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
271}
272
273ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
274{
Mathias Agopianbb641242010-05-18 17:06:55 -0700275 if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800276 return BAD_VALUE;
277 volatile surface_flinger_cblk_t const * cblk = get_cblk();
278 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
279 return dcblk->w;
280}
281
282ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
283{
Mathias Agopianbb641242010-05-18 17:06:55 -0700284 if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800285 return BAD_VALUE;
286 volatile surface_flinger_cblk_t const * cblk = get_cblk();
287 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
288 return dcblk->h;
289}
290
291ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
292{
Mathias Agopianbb641242010-05-18 17:06:55 -0700293 if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800294 return BAD_VALUE;
295 volatile surface_flinger_cblk_t const * cblk = get_cblk();
296 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
297 return dcblk->orientation;
298}
299
300ssize_t SurfaceComposerClient::getNumberOfDisplays()
301{
302 volatile surface_flinger_cblk_t const * cblk = get_cblk();
303 uint32_t connected = cblk->connected;
304 int n = 0;
305 while (connected) {
306 if (connected&1) n++;
307 connected >>= 1;
308 }
309 return n;
310}
311
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700312
313void SurfaceComposerClient::signalServer()
314{
315 mSignalServer->signal();
316}
317
Mathias Agopian01b76682009-04-16 20:04:08 -0700318sp<SurfaceControl> SurfaceComposerClient::createSurface(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800319 int pid,
320 DisplayID display,
321 uint32_t w,
322 uint32_t h,
323 PixelFormat format,
324 uint32_t flags)
325{
Mathias Agopian285dbde2010-03-01 16:09:43 -0800326 String8 name;
327 const size_t SIZE = 128;
328 char buffer[SIZE];
329 snprintf(buffer, SIZE, "<pid_%d>", getpid());
330 name.append(buffer);
331
332 return SurfaceComposerClient::createSurface(pid, name, display,
333 w, h, format, flags);
334
335}
336
337sp<SurfaceControl> SurfaceComposerClient::createSurface(
338 int pid,
339 const String8& name,
340 DisplayID display,
341 uint32_t w,
342 uint32_t h,
343 PixelFormat format,
344 uint32_t flags)
345{
Mathias Agopian01b76682009-04-16 20:04:08 -0700346 sp<SurfaceControl> result;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800347 if (mStatus == NO_ERROR) {
348 ISurfaceFlingerClient::surface_data_t data;
Mathias Agopian285dbde2010-03-01 16:09:43 -0800349 sp<ISurface> surface = mClient->createSurface(&data, pid, name,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800350 display, w, h, format, flags);
351 if (surface != 0) {
Mathias Agopianbb641242010-05-18 17:06:55 -0700352 if (uint32_t(data.token) < SharedBufferStack::NUM_LAYERS_MAX) {
Mathias Agopian01b76682009-04-16 20:04:08 -0700353 result = new SurfaceControl(this, surface, data, w, h, format, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800354 }
355 }
356 }
357 return result;
358}
359
360status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
361{
362 if (mStatus != NO_ERROR)
363 return mStatus;
364
365 // it's okay to destroy a surface while a transaction is open,
366 // (transactions really are a client-side concept)
367 // however, this indicates probably a misuse of the API or a bug
368 // in the client code.
369 LOGW_IF(mTransactionOpen,
370 "Destroying surface while a transaction is open. "
371 "Client %p: destroying surface %d, mTransactionOpen=%d",
372 this, sid, mTransactionOpen);
373
374 status_t err = mClient->destroySurface(sid);
375 return err;
376}
377
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800378void SurfaceComposerClient::openGlobalTransaction()
379{
380 Mutex::Autolock _l(gLock);
381
382 if (gOpenTransactions.size()) {
383 LOGE("openGlobalTransaction() called more than once. skipping.");
384 return;
385 }
386
387 const size_t N = gActiveConnections.size();
388 VERBOSE("openGlobalTransaction (%ld clients)", N);
389 for (size_t i=0; i<N; i++) {
Matt Fischer166bcf92010-02-22 17:40:46 -0600390 sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote());
391 if (client != 0 && gOpenTransactions.indexOf(client) < 0) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800392 if (client->openTransaction() == NO_ERROR) {
393 if (gOpenTransactions.add(client) < 0) {
394 // Ooops!
395 LOGE( "Unable to add a SurfaceComposerClient "
396 "to the global transaction set (out of memory?)");
397 client->closeTransaction();
398 // let it go, it'll fail later when the user
399 // tries to do something with the transaction
400 }
401 } else {
402 LOGE("openTransaction on client %p failed", client.get());
403 // let it go, it'll fail later when the user
404 // tries to do something with the transaction
405 }
406 }
407 }
408}
409
410void SurfaceComposerClient::closeGlobalTransaction()
411{
412 gLock.lock();
413 SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
414 gOpenTransactions.clear();
415 gLock.unlock();
416
417 const size_t N = clients.size();
418 VERBOSE("closeGlobalTransaction (%ld clients)", N);
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700419
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700420 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700421 sm->openGlobalTransaction();
422 for (size_t i=0; i<N; i++) {
423 clients[i]->closeTransaction();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800424 }
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700425 sm->closeGlobalTransaction();
426
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800427}
428
Mathias Agopiancbb288b2009-09-07 16:32:45 -0700429
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800430status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
431{
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700432 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800433 return sm->freezeDisplay(dpy, flags);
434}
435
436status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
437{
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700438 sp<ISurfaceComposer> sm(getComposerService());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800439 return sm->unfreezeDisplay(dpy, flags);
440}
441
Mathias Agopianc08731e2009-03-27 18:11:38 -0700442int SurfaceComposerClient::setOrientation(DisplayID dpy,
443 int orientation, uint32_t flags)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800444{
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700445 sp<ISurfaceComposer> sm(getComposerService());
Mathias Agopianc08731e2009-03-27 18:11:38 -0700446 return sm->setOrientation(dpy, orientation, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800447}
448
449status_t SurfaceComposerClient::openTransaction()
450{
451 if (mStatus != NO_ERROR)
452 return mStatus;
453 Mutex::Autolock _l(mLock);
454 VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
455 this, mTransactionOpen);
456 mTransactionOpen++;
457 if (mPrebuiltLayerState == 0) {
458 mPrebuiltLayerState = new layer_state_t;
459 }
460 return NO_ERROR;
461}
462
463
464status_t SurfaceComposerClient::closeTransaction()
465{
466 if (mStatus != NO_ERROR)
467 return mStatus;
468
469 Mutex::Autolock _l(mLock);
470
471 VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
472 this, mTransactionOpen);
473
474 if (mTransactionOpen <= 0) {
475 LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
476 "called more times than openTransaction()",
477 this, mTransactionOpen);
478 return INVALID_OPERATION;
479 }
480
481 if (mTransactionOpen >= 2) {
482 mTransactionOpen--;
483 return NO_ERROR;
484 }
485
486 mTransactionOpen = 0;
487 const ssize_t count = mStates.size();
488 if (count) {
489 mClient->setState(count, mStates.array());
490 mStates.clear();
491 }
492 return NO_ERROR;
493}
494
Mathias Agopian631f3582010-05-25 17:51:34 -0700495layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800496{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800497 // API usage error, do nothing.
498 if (mTransactionOpen<=0) {
499 LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
500 this, int(index), mTransactionOpen);
501 return 0;
502 }
503
504 // use mPrebuiltLayerState just to find out if we already have it
505 layer_state_t& dummy = *mPrebuiltLayerState;
506 dummy.surface = index;
507 ssize_t i = mStates.indexOf(dummy);
508 if (i < 0) {
509 // we don't have it, add an initialized layer_state to our list
510 i = mStates.add(dummy);
511 }
512 return mStates.editArray() + i;
513}
514
Mathias Agopian631f3582010-05-25 17:51:34 -0700515layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800516{
517 layer_state_t* s;
518 mLock.lock();
Mathias Agopian631f3582010-05-25 17:51:34 -0700519 s = get_state_l(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800520 if (!s) mLock.unlock();
521 return s;
522}
523
Mathias Agopian631f3582010-05-25 17:51:34 -0700524void SurfaceComposerClient::unlockLayerState()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800525{
526 mLock.unlock();
527}
528
Mathias Agopian62185b72009-04-16 16:19:50 -0700529status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800530{
Mathias Agopian631f3582010-05-25 17:51:34 -0700531 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800532 if (!s) return BAD_INDEX;
533 s->what |= ISurfaceComposer::ePositionChanged;
534 s->x = x;
535 s->y = y;
Mathias Agopian631f3582010-05-25 17:51:34 -0700536 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800537 return NO_ERROR;
538}
539
Mathias Agopian62185b72009-04-16 16:19:50 -0700540status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800541{
Mathias Agopian631f3582010-05-25 17:51:34 -0700542 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800543 if (!s) return BAD_INDEX;
544 s->what |= ISurfaceComposer::eSizeChanged;
545 s->w = w;
546 s->h = h;
Mathias Agopian631f3582010-05-25 17:51:34 -0700547 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800548 return NO_ERROR;
549}
550
Mathias Agopian62185b72009-04-16 16:19:50 -0700551status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800552{
Mathias Agopian631f3582010-05-25 17:51:34 -0700553 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800554 if (!s) return BAD_INDEX;
555 s->what |= ISurfaceComposer::eLayerChanged;
556 s->z = z;
Mathias Agopian631f3582010-05-25 17:51:34 -0700557 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800558 return NO_ERROR;
559}
560
Mathias Agopian62185b72009-04-16 16:19:50 -0700561status_t SurfaceComposerClient::hide(SurfaceID id)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800562{
Mathias Agopian62185b72009-04-16 16:19:50 -0700563 return setFlags(id, ISurfaceComposer::eLayerHidden,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800564 ISurfaceComposer::eLayerHidden);
565}
566
Mathias Agopian62185b72009-04-16 16:19:50 -0700567status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800568{
Mathias Agopian62185b72009-04-16 16:19:50 -0700569 return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800570}
571
Mathias Agopian62185b72009-04-16 16:19:50 -0700572status_t SurfaceComposerClient::freeze(SurfaceID id)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800573{
Mathias Agopian62185b72009-04-16 16:19:50 -0700574 return setFlags(id, ISurfaceComposer::eLayerFrozen,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800575 ISurfaceComposer::eLayerFrozen);
576}
577
Mathias Agopian62185b72009-04-16 16:19:50 -0700578status_t SurfaceComposerClient::unfreeze(SurfaceID id)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800579{
Mathias Agopian62185b72009-04-16 16:19:50 -0700580 return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800581}
582
Mathias Agopian62185b72009-04-16 16:19:50 -0700583status_t SurfaceComposerClient::setFlags(SurfaceID id,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800584 uint32_t flags, uint32_t mask)
585{
Mathias Agopian631f3582010-05-25 17:51:34 -0700586 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800587 if (!s) return BAD_INDEX;
588 s->what |= ISurfaceComposer::eVisibilityChanged;
589 s->flags &= ~mask;
590 s->flags |= (flags & mask);
591 s->mask |= mask;
Mathias Agopian631f3582010-05-25 17:51:34 -0700592 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800593 return NO_ERROR;
594}
595
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800596status_t SurfaceComposerClient::setTransparentRegionHint(
Mathias Agopian62185b72009-04-16 16:19:50 -0700597 SurfaceID id, const Region& transparentRegion)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800598{
Mathias Agopian631f3582010-05-25 17:51:34 -0700599 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800600 if (!s) return BAD_INDEX;
601 s->what |= ISurfaceComposer::eTransparentRegionChanged;
602 s->transparentRegion = transparentRegion;
Mathias Agopian631f3582010-05-25 17:51:34 -0700603 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800604 return NO_ERROR;
605}
606
Mathias Agopian62185b72009-04-16 16:19:50 -0700607status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800608{
Mathias Agopian631f3582010-05-25 17:51:34 -0700609 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800610 if (!s) return BAD_INDEX;
611 s->what |= ISurfaceComposer::eAlphaChanged;
612 s->alpha = alpha;
Mathias Agopian631f3582010-05-25 17:51:34 -0700613 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800614 return NO_ERROR;
615}
616
617status_t SurfaceComposerClient::setMatrix(
Mathias Agopian62185b72009-04-16 16:19:50 -0700618 SurfaceID id,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800619 float dsdx, float dtdx,
620 float dsdy, float dtdy )
621{
Mathias Agopian631f3582010-05-25 17:51:34 -0700622 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800623 if (!s) return BAD_INDEX;
624 s->what |= ISurfaceComposer::eMatrixChanged;
625 layer_state_t::matrix22_t matrix;
626 matrix.dsdx = dsdx;
627 matrix.dtdx = dtdx;
628 matrix.dsdy = dsdy;
629 matrix.dtdy = dtdy;
630 s->matrix = matrix;
Mathias Agopian631f3582010-05-25 17:51:34 -0700631 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800632 return NO_ERROR;
633}
634
Mathias Agopian62185b72009-04-16 16:19:50 -0700635status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800636{
Mathias Agopian631f3582010-05-25 17:51:34 -0700637 layer_state_t* s = lockLayerState(id);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800638 if (!s) return BAD_INDEX;
639 s->what |= ISurfaceComposer::eFreezeTintChanged;
640 s->tint = tint;
Mathias Agopian631f3582010-05-25 17:51:34 -0700641 unlockLayerState();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800642 return NO_ERROR;
643}
644
645}; // namespace android
646