blob: fe803ff24964f69c7173eb74c5f31bced05797d8 [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>
32#include <utils/IPCThreadState.h>
33#include <utils/IServiceManager.h>
34#include <utils/IMemory.h>
35#include <utils/Log.h>
36
37#include <ui/ISurfaceComposer.h>
38#include <ui/ISurfaceFlingerClient.h>
39#include <ui/ISurface.h>
40#include <ui/SurfaceComposerClient.h>
41#include <ui/DisplayInfo.h>
42#include <ui/Rect.h>
43#include <ui/Point.h>
44
45#include <private/ui/SharedState.h>
46#include <private/ui/LayerState.h>
47#include <private/ui/SurfaceFlingerSynchro.h>
48
49#include <pixelflinger/pixelflinger.h>
50
51#include <utils/BpBinder.h>
52
53#define VERBOSE(...) ((void)0)
54//#define VERBOSE LOGD
55
56#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
57#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
58
59namespace android {
60
61// ---------------------------------------------------------------------------
62
63// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
64static Mutex gLock;
65static sp<ISurfaceComposer> gSurfaceManager;
66static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
67static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
68static sp<IMemory> gServerCblkMemory;
69static volatile surface_flinger_cblk_t* gServerCblk;
70
71const sp<ISurfaceComposer>& _get_surface_manager()
72{
73 if (gSurfaceManager != 0) {
74 return gSurfaceManager;
75 }
76
77 sp<IBinder> binder;
78 sp<IServiceManager> sm = defaultServiceManager();
79 do {
80 binder = sm->getService(String16("SurfaceFlinger"));
81 if (binder == 0) {
82 LOGW("SurfaceFlinger not published, waiting...");
83 usleep(500000); // 0.5 s
84 }
85 } while(binder == 0);
86 sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
87
88 Mutex::Autolock _l(gLock);
89 if (gSurfaceManager == 0) {
90 gSurfaceManager = sc;
91 }
92 return gSurfaceManager;
93}
94
95static volatile surface_flinger_cblk_t const * get_cblk()
96{
97 if (gServerCblk == 0) {
98 const sp<ISurfaceComposer>& sm(_get_surface_manager());
99 Mutex::Autolock _l(gLock);
100 if (gServerCblk == 0) {
101 gServerCblkMemory = sm->getCblk();
102 LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
103 gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
104 LOGE_IF(gServerCblk==0, "Can't get server control block address");
105 }
106 }
107 return gServerCblk;
108}
109
110// ---------------------------------------------------------------------------
111
112static void copyBlt(const GGLSurface& dst,
113 const GGLSurface& src, const Region& reg)
114{
115 Region::iterator iterator(reg);
116 if (iterator) {
117 // NOTE: dst and src must be the same format
118 Rect r;
119 const size_t bpp = bytesPerPixel(src.format);
120 const size_t dbpr = dst.stride * bpp;
121 const size_t sbpr = src.stride * bpp;
122 while (iterator.iterate(&r)) {
123 ssize_t h = r.bottom - r.top;
124 if (h) {
125 size_t size = (r.right - r.left) * bpp;
126 uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
127 uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
128 if (dbpr==sbpr && size==sbpr) {
129 size *= h;
130 h = 1;
131 }
132 do {
133 memcpy(d, s, size);
134 d += dbpr;
135 s += sbpr;
136 } while (--h > 0);
137 }
138 }
139 }
140}
141
142// ---------------------------------------------------------------------------
143
144surface_flinger_cblk_t::surface_flinger_cblk_t()
145{
146}
147
148// ---------------------------------------------------------------------------
149
150per_client_cblk_t::per_client_cblk_t()
151{
152}
153
154// these functions are used by the clients
155inline status_t per_client_cblk_t::validate(size_t i) const {
156 if (uint32_t(i) >= NUM_LAYERS_MAX)
157 return BAD_INDEX;
158 if (layers[i].swapState & eInvalidSurface)
159 return NO_MEMORY;
160 return NO_ERROR;
161}
162
163int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
164{
165 int32_t index;
166 uint32_t state;
167 int timeout = 0;
168 status_t result;
169 layer_cblk_t * const layer = layers + i;
170 const bool blocking = flags & BLOCKING;
171 const bool inspect = flags & INSPECT;
172
173 do {
174 state = layer->swapState;
175
176 if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
177 LOGE("eNextFlipPending set but eFlipRequested not set, "
178 "layer=%d (lcblk=%p), state=%08x",
179 int(i), layer, int(state));
180 return INVALID_OPERATION;
181 }
182
183 if (UNLIKELY(state&eLocked)) {
184 LOGE("eLocked set when entering lock_layer(), "
185 "layer=%d (lcblk=%p), state=%08x",
186 int(i), layer, int(state));
187 return WOULD_BLOCK;
188 }
189
190
191 if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
192 | eInvalidSurface))
193 {
194 int32_t resizeIndex;
195 Mutex::Autolock _l(lock);
196 // might block for a very short amount of time
197 // will never cause the server to block (trylock())
198
199 goto start_loop_here;
200
201 // We block the client if:
202 // eNextFlipPending: we've used both buffers already, so we need to
203 // wait for one to become availlable.
204 // eResizeRequested: the buffer we're going to acquire is being
205 // resized. Block until it is done.
206 // eFlipRequested && eBusy: the buffer we're going to acquire is
207 // currently in use by the server.
208 // eInvalidSurface: this is a special case, we don't block in this
209 // case, we just return an error.
210
211 while((state & (eNextFlipPending|eInvalidSurface)) ||
212 (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
213 ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
214 {
215 if (state & eInvalidSurface)
216 return NO_MEMORY;
217
218 if (!blocking)
219 return WOULD_BLOCK;
220
221 timeout = 0;
222 result = cv.waitRelative(lock, seconds(1));
223 if (__builtin_expect(result!=NO_ERROR, false)) {
224 const int newState = layer->swapState;
225 LOGW( "lock_layer timed out (is the CPU pegged?) "
226 "layer=%d, lcblk=%p, state=%08x (was %08x)",
227 int(i), layer, newState, int(state));
228 timeout = newState != int(state);
229 }
230
231 start_loop_here:
232 state = layer->swapState;
233 resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
234 }
235
236 LOGW_IF(timeout,
237 "lock_layer() timed out but didn't appear to need "
238 "to be locked and we recovered "
239 "(layer=%d, lcblk=%p, state=%08x)",
240 int(i), layer, int(state));
241 }
242
243 // eFlipRequested is not set and cannot be set by another thread: it's
244 // safe to use the first buffer without synchronization.
245
246 // Choose the index depending on eFlipRequested.
247 // When it's set, choose the 'other' buffer.
248 index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
249
250 // make sure this buffer is valid
251 if (layer->surface[index].bits_offset < 0) {
252 return status_t(layer->surface[index].bits_offset);
253 }
254
255 if (inspect) {
256 // we just want to inspect this layer. don't lock it.
257 goto done;
258 }
259
260 // last thing before we're done, we need to atomically lock the state
261 } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
262
263 VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
264 int(i), layer, int(index), int(state));
265
266 // store the index of the locked buffer (for client use only)
267 layer->flags &= ~eBufferIndex;
268 layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
269
270done:
271 return index;
272}
273
274uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
275{
276 // atomically set eFlipRequested and clear eLocked and optionnaly
277 // set eNextFlipPending if eFlipRequested was already set
278
279 layer_cblk_t * const layer = layers + i;
280 int32_t oldvalue, newvalue;
281 do {
282 oldvalue = layer->swapState;
283 // get current value
284
285 newvalue = oldvalue & ~eLocked;
286 // clear eLocked
287
288 newvalue |= eFlipRequested;
289 // set eFlipRequested
290
291 if (oldvalue & eFlipRequested)
292 newvalue |= eNextFlipPending;
293 // if eFlipRequested was alread set, set eNextFlipPending
294
295 } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
296
297 VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
298 int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
299 int(newvalue));
300
301 // from this point, the server can kick in at anytime and use the first
302 // buffer, so we cannot use it anymore, and we must use the 'other'
303 // buffer instead (or wait if it is not availlable yet, see lock_layer).
304
305 return newvalue;
306}
307
308void per_client_cblk_t::unlock_layer(size_t i)
309{
310 layer_cblk_t * const layer = layers + i;
311 android_atomic_and(~eLocked, &layer->swapState);
312}
313
314// ---------------------------------------------------------------------------
315
316static inline int compare_type( const layer_state_t& lhs,
317 const layer_state_t& rhs) {
318 if (lhs.surface < rhs.surface) return -1;
319 if (lhs.surface > rhs.surface) return 1;
320 return 0;
321}
322
323SurfaceComposerClient::SurfaceComposerClient()
324{
325 const sp<ISurfaceComposer>& sm(_get_surface_manager());
326 if (sm == 0) {
327 _init(0, 0);
328 return;
329 }
330
331 _init(sm, sm->createConnection());
332
333 if (mClient != 0) {
334 Mutex::Autolock _l(gLock);
335 VERBOSE("Adding client %p to map", this);
336 gActiveConnections.add(mClient->asBinder(), this);
337 }
338}
339
340SurfaceComposerClient::SurfaceComposerClient(
341 const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
342{
343 _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
344}
345
346void SurfaceComposerClient::_init(
347 const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
348{
349 VERBOSE("Creating client %p, conn %p", this, conn.get());
350
351 mSignalServer = 0;
352 mPrebuiltLayerState = 0;
353 mTransactionOpen = 0;
354 mStatus = NO_ERROR;
355 mControl = 0;
356
357 mClient = conn;
358 if (mClient == 0) {
359 mStatus = NO_INIT;
360 return;
361 }
362
363 mClient->getControlBlocks(&mControlMemory);
364 mSignalServer = new SurfaceFlingerSynchro(sm);
365 mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
366}
367
368SurfaceComposerClient::~SurfaceComposerClient()
369{
370 VERBOSE("Destroying client %p, conn %p", this, mClient.get());
371 dispose();
372}
373
374status_t SurfaceComposerClient::initCheck() const
375{
376 return mStatus;
377}
378
379status_t SurfaceComposerClient::validateSurface(
380 per_client_cblk_t const* cblk, Surface const * surface)
381{
382 SurfaceID index = surface->ID();
383 if (cblk == 0) {
384 LOGE("cblk is null (surface id=%d, identity=%u)",
385 index, surface->getIdentity());
386 return NO_INIT;
387 }
388
389 status_t err = cblk->validate(index);
390 if (err != NO_ERROR) {
391 LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
392 index, surface->getIdentity(), err, strerror(-err));
393 return err;
394 }
395
396 if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
397 LOGE("using an invalid surface id=%d, identity=%u should be %d",
398 index, surface->getIdentity(), cblk->layers[index].identity);
399 return NO_INIT;
400 }
401
402 return NO_ERROR;
403}
404
405sp<IBinder> SurfaceComposerClient::connection() const
406{
407 return (mClient != 0) ? mClient->asBinder() : 0;
408}
409
410sp<SurfaceComposerClient>
411SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
412{
413 sp<SurfaceComposerClient> client;
414
415 { // scope for lock
416 Mutex::Autolock _l(gLock);
417 client = gActiveConnections.valueFor(conn);
418 }
419
420 if (client == 0) {
421 // Need to make a new client.
422 const sp<ISurfaceComposer>& sm(_get_surface_manager());
423 client = new SurfaceComposerClient(sm, conn);
424 if (client != 0 && client->initCheck() == NO_ERROR) {
425 Mutex::Autolock _l(gLock);
426 gActiveConnections.add(conn, client);
427 //LOGD("we have %d connections", gActiveConnections.size());
428 } else {
429 client.clear();
430 }
431 }
432
433 return client;
434}
435
436void SurfaceComposerClient::dispose()
437{
438 // this can be called more than once.
439
440 sp<IMemory> controlMemory;
441 sp<ISurfaceFlingerClient> client;
442 sp<IMemoryHeap> surfaceHeap;
443
444 {
445 Mutex::Autolock _lg(gLock);
446 Mutex::Autolock _lm(mLock);
447
448 delete mSignalServer;
449 mSignalServer = 0;
450
451 if (mClient != 0) {
452 client = mClient;
453 mClient.clear();
454
455 ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
456 if (i >= 0 && gActiveConnections.valueAt(i) == this) {
457 VERBOSE("Removing client %p from map at %d", this, int(i));
458 gActiveConnections.removeItemsAt(i);
459 }
460 }
461
462 delete mPrebuiltLayerState;
463 mPrebuiltLayerState = 0;
464 controlMemory = mControlMemory;
465 surfaceHeap = mSurfaceHeap;
466 mControlMemory.clear();
467 mSurfaceHeap.clear();
468 mControl = 0;
469 mStatus = NO_INIT;
470 }
471}
472
473status_t SurfaceComposerClient::getDisplayInfo(
474 DisplayID dpy, DisplayInfo* info)
475{
476 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
477 return BAD_VALUE;
478
479 volatile surface_flinger_cblk_t const * cblk = get_cblk();
480 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
481
482 info->w = dcblk->w;
483 info->h = dcblk->h;
484 info->orientation = dcblk->orientation;
485 info->xdpi = dcblk->xdpi;
486 info->ydpi = dcblk->ydpi;
487 info->fps = dcblk->fps;
488 info->density = dcblk->density;
489 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
490}
491
492ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
493{
494 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
495 return BAD_VALUE;
496 volatile surface_flinger_cblk_t const * cblk = get_cblk();
497 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
498 return dcblk->w;
499}
500
501ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
502{
503 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
504 return BAD_VALUE;
505 volatile surface_flinger_cblk_t const * cblk = get_cblk();
506 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
507 return dcblk->h;
508}
509
510ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
511{
512 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
513 return BAD_VALUE;
514 volatile surface_flinger_cblk_t const * cblk = get_cblk();
515 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
516 return dcblk->orientation;
517}
518
519ssize_t SurfaceComposerClient::getNumberOfDisplays()
520{
521 volatile surface_flinger_cblk_t const * cblk = get_cblk();
522 uint32_t connected = cblk->connected;
523 int n = 0;
524 while (connected) {
525 if (connected&1) n++;
526 connected >>= 1;
527 }
528 return n;
529}
530
531sp<Surface> SurfaceComposerClient::createSurface(
532 int pid,
533 DisplayID display,
534 uint32_t w,
535 uint32_t h,
536 PixelFormat format,
537 uint32_t flags)
538{
539 sp<Surface> result;
540 if (mStatus == NO_ERROR) {
541 ISurfaceFlingerClient::surface_data_t data;
542 sp<ISurface> surface = mClient->createSurface(&data, pid,
543 display, w, h, format, flags);
544 if (surface != 0) {
545 if (uint32_t(data.token) < NUM_LAYERS_MAX) {
546 result = new Surface(this, surface, data, w, h, format, flags);
547 }
548 }
549 }
550 return result;
551}
552
553status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
554{
555 if (mStatus != NO_ERROR)
556 return mStatus;
557
558 // it's okay to destroy a surface while a transaction is open,
559 // (transactions really are a client-side concept)
560 // however, this indicates probably a misuse of the API or a bug
561 // in the client code.
562 LOGW_IF(mTransactionOpen,
563 "Destroying surface while a transaction is open. "
564 "Client %p: destroying surface %d, mTransactionOpen=%d",
565 this, sid, mTransactionOpen);
566
567 status_t err = mClient->destroySurface(sid);
568 return err;
569}
570
571status_t SurfaceComposerClient::nextBuffer(Surface* surface,
572 Surface::SurfaceInfo* info)
573{
574 SurfaceID index = surface->ID();
575 per_client_cblk_t* const cblk = mControl;
576 status_t err = validateSurface(cblk, surface);
577 if (err != NO_ERROR)
578 return err;
579
580 int32_t backIdx = surface->mBackbufferIndex;
581 layer_cblk_t* const lcblk = &(cblk->layers[index]);
582 const surface_info_t* const front = lcblk->surface + (1-backIdx);
583 info->w = front->w;
584 info->h = front->h;
585 info->format = front->format;
586 info->base = surface->heapBase(1-backIdx);
587 info->bits = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
588 info->bpr = front->bpr;
589
590 return 0;
591}
592
593status_t SurfaceComposerClient::lockSurface(
594 Surface* surface,
595 Surface::SurfaceInfo* other,
596 Region* dirty,
597 bool blocking)
598{
599 Mutex::Autolock _l(surface->getLock());
600
601 SurfaceID index = surface->ID();
602 per_client_cblk_t* const cblk = mControl;
603 status_t err = validateSurface(cblk, surface);
604 if (err != NO_ERROR)
605 return err;
606
607 int32_t backIdx = cblk->lock_layer(size_t(index),
608 per_client_cblk_t::BLOCKING);
609 if (backIdx >= 0) {
610 surface->mBackbufferIndex = backIdx;
611 layer_cblk_t* const lcblk = &(cblk->layers[index]);
612 const surface_info_t* const back = lcblk->surface + backIdx;
613 const surface_info_t* const front = lcblk->surface + (1-backIdx);
614 other->w = back->w;
615 other->h = back->h;
616 other->format = back->format;
617 other->base = surface->heapBase(backIdx);
618 other->bits = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
619 other->bpr = back->bpr;
620
621 const Rect bounds(other->w, other->h);
622 Region newDirtyRegion;
623
624 if (back->flags & surface_info_t::eBufferDirty) {
625 /* it is safe to write *back here, because we're guaranteed
626 * SurfaceFlinger is not touching it (since it just granted
627 * access to us) */
628 const_cast<surface_info_t*>(back)->flags &=
629 ~surface_info_t::eBufferDirty;
630
631 // content is meaningless in this case and the whole surface
632 // needs to be redrawn.
633
634 newDirtyRegion.set(bounds);
635 if (dirty) {
636 *dirty = newDirtyRegion;
637 }
638
639 //if (bytesPerPixel(other->format) == 4) {
640 // android_memset32(
641 // (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
642 //} else {
643 // android_memset16( // fill with green
644 // (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
645 //}
646 }
647 else
648 {
649 if (dirty) {
650 dirty->andSelf(Region(bounds));
651 newDirtyRegion = *dirty;
652 } else {
653 newDirtyRegion.set(bounds);
654 }
655
656 Region copyback;
657 if (!(lcblk->flags & eNoCopyBack)) {
658 const Region previousDirtyRegion(surface->dirtyRegion());
659 copyback = previousDirtyRegion.subtract(newDirtyRegion);
660 }
661
662 if (!copyback.isEmpty()) {
663 // copy front to back
664 GGLSurface cb;
665 cb.version = sizeof(GGLSurface);
666 cb.width = back->w;
667 cb.height = back->h;
668 cb.stride = back->stride;
669 cb.data = (GGLubyte*)surface->heapBase(backIdx);
670 cb.data += back->bits_offset;
671 cb.format = back->format;
672
673 GGLSurface t;
674 t.version = sizeof(GGLSurface);
675 t.width = front->w;
676 t.height = front->h;
677 t.stride = front->stride;
678 t.data = (GGLubyte*)surface->heapBase(1-backIdx);
679 t.data += front->bits_offset;
680 t.format = front->format;
681
682 //const Region copyback(lcblk->region + 1-backIdx);
683 copyBlt(cb, t, copyback);
684 }
685 }
686
687 // update dirty region
688 surface->setDirtyRegion(newDirtyRegion);
689 }
690 return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
691}
692
693void SurfaceComposerClient::_signal_server()
694{
695 mSignalServer->signal();
696}
697
698void SurfaceComposerClient::_send_dirty_region(
699 layer_cblk_t* lcblk, const Region& dirty)
700{
701 const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
702 flat_region_t* flat_region = lcblk->region + index;
703 status_t err = dirty.write(flat_region, sizeof(flat_region_t));
704 if (err < NO_ERROR) {
705 // region doesn't fit, use the bounds
706 const Region reg(dirty.bounds());
707 reg.write(flat_region, sizeof(flat_region_t));
708 }
709}
710
711status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
712{
713 Mutex::Autolock _l(surface->getLock());
714
715 SurfaceID index = surface->ID();
716 per_client_cblk_t* const cblk = mControl;
717 status_t err = validateSurface(cblk, surface);
718 if (err != NO_ERROR)
719 return err;
720
721 Region dirty(surface->dirtyRegion());
722 const Rect& swapRect(surface->swapRectangle());
723 if (swapRect.isValid()) {
724 dirty.set(swapRect);
725 }
726
727 // transmit the dirty region
728 layer_cblk_t* const lcblk = &(cblk->layers[index]);
729 _send_dirty_region(lcblk, dirty);
730 uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
731 if (!(newstate & eNextFlipPending))
732 _signal_server();
733 return NO_ERROR;
734}
735
736status_t SurfaceComposerClient::unlockSurface(Surface* surface)
737{
738 Mutex::Autolock _l(surface->getLock());
739
740 SurfaceID index = surface->ID();
741 per_client_cblk_t* const cblk = mControl;
742 status_t err = validateSurface(cblk, surface);
743 if (err != NO_ERROR)
744 return err;
745
746 layer_cblk_t* const lcblk = &(cblk->layers[index]);
747 cblk->unlock_layer(size_t(index));
748 return NO_ERROR;
749}
750
751void SurfaceComposerClient::openGlobalTransaction()
752{
753 Mutex::Autolock _l(gLock);
754
755 if (gOpenTransactions.size()) {
756 LOGE("openGlobalTransaction() called more than once. skipping.");
757 return;
758 }
759
760 const size_t N = gActiveConnections.size();
761 VERBOSE("openGlobalTransaction (%ld clients)", N);
762 for (size_t i=0; i<N; i++) {
763 sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
764 if (gOpenTransactions.indexOf(client) < 0) {
765 if (client->openTransaction() == NO_ERROR) {
766 if (gOpenTransactions.add(client) < 0) {
767 // Ooops!
768 LOGE( "Unable to add a SurfaceComposerClient "
769 "to the global transaction set (out of memory?)");
770 client->closeTransaction();
771 // let it go, it'll fail later when the user
772 // tries to do something with the transaction
773 }
774 } else {
775 LOGE("openTransaction on client %p failed", client.get());
776 // let it go, it'll fail later when the user
777 // tries to do something with the transaction
778 }
779 }
780 }
781}
782
783void SurfaceComposerClient::closeGlobalTransaction()
784{
785 gLock.lock();
786 SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
787 gOpenTransactions.clear();
788 gLock.unlock();
789
790 const size_t N = clients.size();
791 VERBOSE("closeGlobalTransaction (%ld clients)", N);
792 if (N == 1) {
793 clients[0]->closeTransaction();
794 } else {
795 const sp<ISurfaceComposer>& sm(_get_surface_manager());
796 sm->openGlobalTransaction();
797 for (size_t i=0; i<N; i++) {
798 clients[i]->closeTransaction();
799 }
800 sm->closeGlobalTransaction();
801 }
802}
803
804status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
805{
806 const sp<ISurfaceComposer>& sm(_get_surface_manager());
807 return sm->freezeDisplay(dpy, flags);
808}
809
810status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
811{
812 const sp<ISurfaceComposer>& sm(_get_surface_manager());
813 return sm->unfreezeDisplay(dpy, flags);
814}
815
Mathias Agopian66b8ec92009-03-27 16:10:37 -0700816int SurfaceComposerClient::setOrientation(DisplayID dpy,
817 int orientation, uint32_t flags)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818{
819 const sp<ISurfaceComposer>& sm(_get_surface_manager());
Mathias Agopian66b8ec92009-03-27 16:10:37 -0700820 return sm->setOrientation(dpy, orientation, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821}
822
823status_t SurfaceComposerClient::openTransaction()
824{
825 if (mStatus != NO_ERROR)
826 return mStatus;
827 Mutex::Autolock _l(mLock);
828 VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)",
829 this, mTransactionOpen);
830 mTransactionOpen++;
831 if (mPrebuiltLayerState == 0) {
832 mPrebuiltLayerState = new layer_state_t;
833 }
834 return NO_ERROR;
835}
836
837
838status_t SurfaceComposerClient::closeTransaction()
839{
840 if (mStatus != NO_ERROR)
841 return mStatus;
842
843 Mutex::Autolock _l(mLock);
844
845 VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)",
846 this, mTransactionOpen);
847
848 if (mTransactionOpen <= 0) {
849 LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
850 "called more times than openTransaction()",
851 this, mTransactionOpen);
852 return INVALID_OPERATION;
853 }
854
855 if (mTransactionOpen >= 2) {
856 mTransactionOpen--;
857 return NO_ERROR;
858 }
859
860 mTransactionOpen = 0;
861 const ssize_t count = mStates.size();
862 if (count) {
863 mClient->setState(count, mStates.array());
864 mStates.clear();
865 }
866 return NO_ERROR;
867}
868
869layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
870{
871 SurfaceID index = surface->ID();
872 per_client_cblk_t* const cblk = mControl;
873 status_t err = validateSurface(cblk, surface.get());
874 if (err != NO_ERROR)
875 return 0;
876
877 // API usage error, do nothing.
878 if (mTransactionOpen<=0) {
879 LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
880 this, int(index), mTransactionOpen);
881 return 0;
882 }
883
884 // use mPrebuiltLayerState just to find out if we already have it
885 layer_state_t& dummy = *mPrebuiltLayerState;
886 dummy.surface = index;
887 ssize_t i = mStates.indexOf(dummy);
888 if (i < 0) {
889 // we don't have it, add an initialized layer_state to our list
890 i = mStates.add(dummy);
891 }
892 return mStates.editArray() + i;
893}
894
895layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
896{
897 layer_state_t* s;
898 mLock.lock();
899 s = _get_state_l(surface);
900 if (!s) mLock.unlock();
901 return s;
902}
903
904void SurfaceComposerClient::_unlockLayerState()
905{
906 mLock.unlock();
907}
908
909status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
910{
911 layer_state_t* s = _lockLayerState(surface);
912 if (!s) return BAD_INDEX;
913 s->what |= ISurfaceComposer::ePositionChanged;
914 s->x = x;
915 s->y = y;
916 _unlockLayerState();
917 return NO_ERROR;
918}
919
920status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
921{
922 layer_state_t* s = _lockLayerState(surface);
923 if (!s) return BAD_INDEX;
924 s->what |= ISurfaceComposer::eSizeChanged;
925 s->w = w;
926 s->h = h;
927 _unlockLayerState();
928 return NO_ERROR;
929}
930
931status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
932{
933 layer_state_t* s = _lockLayerState(surface);
934 if (!s) return BAD_INDEX;
935 s->what |= ISurfaceComposer::eLayerChanged;
936 s->z = z;
937 _unlockLayerState();
938 return NO_ERROR;
939}
940
941status_t SurfaceComposerClient::hide(Surface* surface)
942{
943 return setFlags(surface, ISurfaceComposer::eLayerHidden,
944 ISurfaceComposer::eLayerHidden);
945}
946
947status_t SurfaceComposerClient::show(Surface* surface, int32_t)
948{
949 return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
950}
951
952status_t SurfaceComposerClient::freeze(Surface* surface)
953{
954 return setFlags(surface, ISurfaceComposer::eLayerFrozen,
955 ISurfaceComposer::eLayerFrozen);
956}
957
958status_t SurfaceComposerClient::unfreeze(Surface* surface)
959{
960 return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
961}
962
963status_t SurfaceComposerClient::setFlags(Surface* surface,
964 uint32_t flags, uint32_t mask)
965{
966 layer_state_t* s = _lockLayerState(surface);
967 if (!s) return BAD_INDEX;
968 s->what |= ISurfaceComposer::eVisibilityChanged;
969 s->flags &= ~mask;
970 s->flags |= (flags & mask);
971 s->mask |= mask;
972 _unlockLayerState();
973 return NO_ERROR;
974}
975
976
977status_t SurfaceComposerClient::setTransparentRegionHint(
978 Surface* surface, const Region& transparentRegion)
979{
980 layer_state_t* s = _lockLayerState(surface);
981 if (!s) return BAD_INDEX;
982 s->what |= ISurfaceComposer::eTransparentRegionChanged;
983 s->transparentRegion = transparentRegion;
984 _unlockLayerState();
985 return NO_ERROR;
986}
987
988status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
989{
990 layer_state_t* s = _lockLayerState(surface);
991 if (!s) return BAD_INDEX;
992 s->what |= ISurfaceComposer::eAlphaChanged;
993 s->alpha = alpha;
994 _unlockLayerState();
995 return NO_ERROR;
996}
997
998status_t SurfaceComposerClient::setMatrix(
999 Surface* surface,
1000 float dsdx, float dtdx,
1001 float dsdy, float dtdy )
1002{
1003 layer_state_t* s = _lockLayerState(surface);
1004 if (!s) return BAD_INDEX;
1005 s->what |= ISurfaceComposer::eMatrixChanged;
1006 layer_state_t::matrix22_t matrix;
1007 matrix.dsdx = dsdx;
1008 matrix.dtdx = dtdx;
1009 matrix.dsdy = dsdy;
1010 matrix.dtdy = dtdy;
1011 s->matrix = matrix;
1012 _unlockLayerState();
1013 return NO_ERROR;
1014}
1015
1016status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
1017{
1018 layer_state_t* s = _lockLayerState(surface);
1019 if (!s) return BAD_INDEX;
1020 s->what |= ISurfaceComposer::eFreezeTintChanged;
1021 s->tint = tint;
1022 _unlockLayerState();
1023 return NO_ERROR;
1024}
1025
1026}; // namespace android
1027