1/*
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 <sys/types.h>
21
22#include <utils/Errors.h>
23#include <utils/Log.h>
24#include <utils/Singleton.h>
25#include <utils/SortedVector.h>
26#include <utils/String8.h>
27#include <utils/threads.h>
28
29#include <binder/IMemory.h>
30#include <binder/IServiceManager.h>
31
32#include <ui/DisplayInfo.h>
33
34#include <gui/ISurface.h>
35#include <gui/ISurfaceComposer.h>
36#include <gui/ISurfaceComposerClient.h>
37#include <gui/SurfaceComposerClient.h>
38
39#include <private/gui/ComposerService.h>
40#include <private/gui/LayerState.h>
41
42namespace android {
43// ---------------------------------------------------------------------------
44
45ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
46
47ComposerService::ComposerService()
48: Singleton<ComposerService>() {
49    Mutex::Autolock _l(mLock);
50    connectLocked();
51}
52
53void ComposerService::connectLocked() {
54    const String16 name("SurfaceFlinger");
55    while (getService(name, &mComposerService) != NO_ERROR) {
56        usleep(250000);
57    }
58    assert(mComposerService != NULL);
59
60    // Create the death listener.
61    class DeathObserver : public IBinder::DeathRecipient {
62        ComposerService& mComposerService;
63        virtual void binderDied(const wp<IBinder>& who) {
64            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
65                  who.unsafe_get());
66            mComposerService.composerServiceDied();
67        }
68     public:
69        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
70    };
71
72    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
73    mComposerService->asBinder()->linkToDeath(mDeathObserver);
74}
75
76/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
77    ComposerService& instance = ComposerService::getInstance();
78    Mutex::Autolock _l(instance.mLock);
79    if (instance.mComposerService == NULL) {
80        ComposerService::getInstance().connectLocked();
81        assert(instance.mComposerService != NULL);
82        ALOGD("ComposerService reconnected");
83    }
84    return instance.mComposerService;
85}
86
87void ComposerService::composerServiceDied()
88{
89    Mutex::Autolock _l(mLock);
90    mComposerService = NULL;
91    mDeathObserver = NULL;
92}
93
94// ---------------------------------------------------------------------------
95
96static inline
97int compare_type(const ComposerState& lhs, const ComposerState& rhs) {
98    if (lhs.client < rhs.client)  return -1;
99    if (lhs.client > rhs.client)  return 1;
100    if (lhs.state.surface < rhs.state.surface)  return -1;
101    if (lhs.state.surface > rhs.state.surface)  return 1;
102    return 0;
103}
104
105static inline
106int compare_type(const DisplayState& lhs, const DisplayState& rhs) {
107    return compare_type(lhs.token, rhs.token);
108}
109
110class Composer : public Singleton<Composer>
111{
112    friend class Singleton<Composer>;
113
114    mutable Mutex               mLock;
115    SortedVector<ComposerState> mComposerStates;
116    SortedVector<DisplayState > mDisplayStates;
117    uint32_t                    mForceSynchronous;
118    bool                        mAnimation;
119
120    Composer() : Singleton<Composer>(),
121        mForceSynchronous(0),
122        mAnimation(false)
123    { }
124
125    void closeGlobalTransactionImpl(bool synchronous);
126    void setAnimationTransactionImpl();
127
128    layer_state_t* getLayerStateLocked(
129            const sp<SurfaceComposerClient>& client, SurfaceID id);
130
131    DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
132
133public:
134    sp<IBinder> createDisplay(const String8& displayName, bool secure);
135    sp<IBinder> getBuiltInDisplay(int32_t id);
136
137    status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
138            float x, float y);
139    status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
140            uint32_t w, uint32_t h);
141    status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
142            int32_t z);
143    status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
144            uint32_t flags, uint32_t mask);
145    status_t setTransparentRegionHint(
146            const sp<SurfaceComposerClient>& client, SurfaceID id,
147            const Region& transparentRegion);
148    status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
149            float alpha);
150    status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
151            float dsdx, float dtdx, float dsdy, float dtdy);
152    status_t setOrientation(int orientation);
153    status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id,
154            const Rect& crop);
155    status_t setLayerStack(const sp<SurfaceComposerClient>& client,
156            SurfaceID id, uint32_t layerStack);
157
158    void setDisplaySurface(const sp<IBinder>& token, const sp<ISurfaceTexture>& surface);
159    void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack);
160    void setDisplayProjection(const sp<IBinder>& token,
161            uint32_t orientation,
162            const Rect& layerStackRect,
163            const Rect& displayRect);
164
165    static void setAnimationTransaction() {
166        Composer::getInstance().setAnimationTransactionImpl();
167    }
168
169    static void closeGlobalTransaction(bool synchronous) {
170        Composer::getInstance().closeGlobalTransactionImpl(synchronous);
171    }
172};
173
174ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
175
176// ---------------------------------------------------------------------------
177
178sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) {
179    return ComposerService::getComposerService()->createDisplay(displayName,
180            secure);
181}
182
183sp<IBinder> Composer::getBuiltInDisplay(int32_t id) {
184    return ComposerService::getComposerService()->getBuiltInDisplay(id);
185}
186
187void Composer::closeGlobalTransactionImpl(bool synchronous) {
188    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
189
190    Vector<ComposerState> transaction;
191    Vector<DisplayState> displayTransaction;
192    uint32_t flags = 0;
193
194    { // scope for the lock
195        Mutex::Autolock _l(mLock);
196        transaction = mComposerStates;
197        mComposerStates.clear();
198
199        displayTransaction = mDisplayStates;
200        mDisplayStates.clear();
201
202        if (synchronous || mForceSynchronous) {
203            flags |= ISurfaceComposer::eSynchronous;
204        }
205        if (mAnimation) {
206            flags |= ISurfaceComposer::eAnimation;
207        }
208
209        mForceSynchronous = false;
210        mAnimation = false;
211    }
212
213   sm->setTransactionState(transaction, displayTransaction, flags);
214}
215
216void Composer::setAnimationTransactionImpl() {
217    Mutex::Autolock _l(mLock);
218    mAnimation = true;
219}
220
221layer_state_t* Composer::getLayerStateLocked(
222        const sp<SurfaceComposerClient>& client, SurfaceID id) {
223
224    ComposerState s;
225    s.client = client->mClient;
226    s.state.surface = id;
227
228    ssize_t index = mComposerStates.indexOf(s);
229    if (index < 0) {
230        // we don't have it, add an initialized layer_state to our list
231        index = mComposerStates.add(s);
232    }
233
234    ComposerState* const out = mComposerStates.editArray();
235    return &(out[index].state);
236}
237
238status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
239        SurfaceID id, float x, float y) {
240    Mutex::Autolock _l(mLock);
241    layer_state_t* s = getLayerStateLocked(client, id);
242    if (!s)
243        return BAD_INDEX;
244    s->what |= layer_state_t::ePositionChanged;
245    s->x = x;
246    s->y = y;
247    return NO_ERROR;
248}
249
250status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
251        SurfaceID id, uint32_t w, uint32_t h) {
252    Mutex::Autolock _l(mLock);
253    layer_state_t* s = getLayerStateLocked(client, id);
254    if (!s)
255        return BAD_INDEX;
256    s->what |= layer_state_t::eSizeChanged;
257    s->w = w;
258    s->h = h;
259
260    // Resizing a surface makes the transaction synchronous.
261    mForceSynchronous = true;
262
263    return NO_ERROR;
264}
265
266status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
267        SurfaceID id, int32_t z) {
268    Mutex::Autolock _l(mLock);
269    layer_state_t* s = getLayerStateLocked(client, id);
270    if (!s)
271        return BAD_INDEX;
272    s->what |= layer_state_t::eLayerChanged;
273    s->z = z;
274    return NO_ERROR;
275}
276
277status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
278        SurfaceID id, uint32_t flags,
279        uint32_t mask) {
280    Mutex::Autolock _l(mLock);
281    layer_state_t* s = getLayerStateLocked(client, id);
282    if (!s)
283        return BAD_INDEX;
284    s->what |= layer_state_t::eVisibilityChanged;
285    s->flags &= ~mask;
286    s->flags |= (flags & mask);
287    s->mask |= mask;
288    return NO_ERROR;
289}
290
291status_t Composer::setTransparentRegionHint(
292        const sp<SurfaceComposerClient>& client, SurfaceID id,
293        const Region& transparentRegion) {
294    Mutex::Autolock _l(mLock);
295    layer_state_t* s = getLayerStateLocked(client, id);
296    if (!s)
297        return BAD_INDEX;
298    s->what |= layer_state_t::eTransparentRegionChanged;
299    s->transparentRegion = transparentRegion;
300    return NO_ERROR;
301}
302
303status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
304        SurfaceID id, float alpha) {
305    Mutex::Autolock _l(mLock);
306    layer_state_t* s = getLayerStateLocked(client, id);
307    if (!s)
308        return BAD_INDEX;
309    s->what |= layer_state_t::eAlphaChanged;
310    s->alpha = alpha;
311    return NO_ERROR;
312}
313
314status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client,
315        SurfaceID id, uint32_t layerStack) {
316    Mutex::Autolock _l(mLock);
317    layer_state_t* s = getLayerStateLocked(client, id);
318    if (!s)
319        return BAD_INDEX;
320    s->what |= layer_state_t::eLayerStackChanged;
321    s->layerStack = layerStack;
322    return NO_ERROR;
323}
324
325status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
326        SurfaceID id, float dsdx, float dtdx,
327        float dsdy, float dtdy) {
328    Mutex::Autolock _l(mLock);
329    layer_state_t* s = getLayerStateLocked(client, id);
330    if (!s)
331        return BAD_INDEX;
332    s->what |= layer_state_t::eMatrixChanged;
333    layer_state_t::matrix22_t matrix;
334    matrix.dsdx = dsdx;
335    matrix.dtdx = dtdx;
336    matrix.dsdy = dsdy;
337    matrix.dtdy = dtdy;
338    s->matrix = matrix;
339    return NO_ERROR;
340}
341
342status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
343        SurfaceID id, const Rect& crop) {
344    Mutex::Autolock _l(mLock);
345    layer_state_t* s = getLayerStateLocked(client, id);
346    if (!s)
347        return BAD_INDEX;
348    s->what |= layer_state_t::eCropChanged;
349    s->crop = crop;
350    return NO_ERROR;
351}
352
353// ---------------------------------------------------------------------------
354
355DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) {
356    DisplayState s;
357    s.token = token;
358    ssize_t index = mDisplayStates.indexOf(s);
359    if (index < 0) {
360        // we don't have it, add an initialized layer_state to our list
361        s.what = 0;
362        index = mDisplayStates.add(s);
363    }
364    return mDisplayStates.editItemAt(index);
365}
366
367void Composer::setDisplaySurface(const sp<IBinder>& token,
368        const sp<ISurfaceTexture>& surface) {
369    Mutex::Autolock _l(mLock);
370    DisplayState& s(getDisplayStateLocked(token));
371    s.surface = surface;
372    s.what |= DisplayState::eSurfaceChanged;
373}
374
375void Composer::setDisplayLayerStack(const sp<IBinder>& token,
376        uint32_t layerStack) {
377    Mutex::Autolock _l(mLock);
378    DisplayState& s(getDisplayStateLocked(token));
379    s.layerStack = layerStack;
380    s.what |= DisplayState::eLayerStackChanged;
381}
382
383void Composer::setDisplayProjection(const sp<IBinder>& token,
384        uint32_t orientation,
385        const Rect& layerStackRect,
386        const Rect& displayRect) {
387    Mutex::Autolock _l(mLock);
388    DisplayState& s(getDisplayStateLocked(token));
389    s.orientation = orientation;
390    s.viewport = layerStackRect;
391    s.frame = displayRect;
392    s.what |= DisplayState::eDisplayProjectionChanged;
393    mForceSynchronous = true; // TODO: do we actually still need this?
394}
395
396// ---------------------------------------------------------------------------
397
398SurfaceComposerClient::SurfaceComposerClient()
399    : mStatus(NO_INIT), mComposer(Composer::getInstance())
400{
401}
402
403void SurfaceComposerClient::onFirstRef() {
404    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
405    if (sm != 0) {
406        sp<ISurfaceComposerClient> conn = sm->createConnection();
407        if (conn != 0) {
408            mClient = conn;
409            mStatus = NO_ERROR;
410        }
411    }
412}
413
414SurfaceComposerClient::~SurfaceComposerClient() {
415    dispose();
416}
417
418status_t SurfaceComposerClient::initCheck() const {
419    return mStatus;
420}
421
422sp<IBinder> SurfaceComposerClient::connection() const {
423    return (mClient != 0) ? mClient->asBinder() : 0;
424}
425
426status_t SurfaceComposerClient::linkToComposerDeath(
427        const sp<IBinder::DeathRecipient>& recipient,
428        void* cookie, uint32_t flags) {
429    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
430    return sm->asBinder()->linkToDeath(recipient, cookie, flags);
431}
432
433void SurfaceComposerClient::dispose() {
434    // this can be called more than once.
435    sp<ISurfaceComposerClient> client;
436    Mutex::Autolock _lm(mLock);
437    if (mClient != 0) {
438        client = mClient; // hold ref while lock is held
439        mClient.clear();
440    }
441    mStatus = NO_INIT;
442}
443
444sp<SurfaceControl> SurfaceComposerClient::createSurface(
445        const String8& name,
446        uint32_t w,
447        uint32_t h,
448        PixelFormat format,
449        uint32_t flags)
450{
451    sp<SurfaceControl> result;
452    if (mStatus == NO_ERROR) {
453        ISurfaceComposerClient::surface_data_t data;
454        sp<ISurface> surface = mClient->createSurface(&data, name,
455                w, h, format, flags);
456        if (surface != 0) {
457            result = new SurfaceControl(this, surface, data);
458        }
459    }
460    return result;
461}
462
463sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName,
464        bool secure) {
465    return Composer::getInstance().createDisplay(displayName, secure);
466}
467
468sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
469    return Composer::getInstance().getBuiltInDisplay(id);
470}
471
472status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
473    if (mStatus != NO_ERROR)
474        return mStatus;
475    status_t err = mClient->destroySurface(sid);
476    return err;
477}
478
479inline Composer& SurfaceComposerClient::getComposer() {
480    return mComposer;
481}
482
483// ----------------------------------------------------------------------------
484
485void SurfaceComposerClient::openGlobalTransaction() {
486    // Currently a no-op
487}
488
489void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
490    Composer::closeGlobalTransaction(synchronous);
491}
492
493void SurfaceComposerClient::setAnimationTransaction() {
494    Composer::setAnimationTransaction();
495}
496
497// ----------------------------------------------------------------------------
498
499status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {
500    return getComposer().setCrop(this, id, crop);
501}
502
503status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
504    return getComposer().setPosition(this, id, x, y);
505}
506
507status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
508    return getComposer().setSize(this, id, w, h);
509}
510
511status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
512    return getComposer().setLayer(this, id, z);
513}
514
515status_t SurfaceComposerClient::hide(SurfaceID id) {
516    return getComposer().setFlags(this, id,
517            layer_state_t::eLayerHidden,
518            layer_state_t::eLayerHidden);
519}
520
521status_t SurfaceComposerClient::show(SurfaceID id) {
522    return getComposer().setFlags(this, id,
523            0,
524            layer_state_t::eLayerHidden);
525}
526
527status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
528        uint32_t mask) {
529    return getComposer().setFlags(this, id, flags, mask);
530}
531
532status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
533        const Region& transparentRegion) {
534    return getComposer().setTransparentRegionHint(this, id, transparentRegion);
535}
536
537status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
538    return getComposer().setAlpha(this, id, alpha);
539}
540
541status_t SurfaceComposerClient::setLayerStack(SurfaceID id, uint32_t layerStack) {
542    return getComposer().setLayerStack(this, id, layerStack);
543}
544
545status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
546        float dsdy, float dtdy) {
547    return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
548}
549
550// ----------------------------------------------------------------------------
551
552void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,
553        const sp<ISurfaceTexture>& surface) {
554    Composer::getInstance().setDisplaySurface(token, surface);
555}
556
557void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token,
558        uint32_t layerStack) {
559    Composer::getInstance().setDisplayLayerStack(token, layerStack);
560}
561
562void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token,
563        uint32_t orientation,
564        const Rect& layerStackRect,
565        const Rect& displayRect) {
566    Composer::getInstance().setDisplayProjection(token, orientation,
567            layerStackRect, displayRect);
568}
569
570// ----------------------------------------------------------------------------
571
572status_t SurfaceComposerClient::getDisplayInfo(
573        const sp<IBinder>& display, DisplayInfo* info)
574{
575    return ComposerService::getComposerService()->getDisplayInfo(display, info);
576}
577
578void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) {
579    ComposerService::getComposerService()->blank(token);
580}
581
582void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
583    ComposerService::getComposerService()->unblank(token);
584}
585
586// ----------------------------------------------------------------------------
587
588ScreenshotClient::ScreenshotClient()
589    : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
590}
591
592status_t ScreenshotClient::update(const sp<IBinder>& display) {
593    sp<ISurfaceComposer> s(ComposerService::getComposerService());
594    if (s == NULL) return NO_INIT;
595    mHeap = 0;
596    return s->captureScreen(display, &mHeap,
597            &mWidth, &mHeight, &mFormat, 0, 0,
598            0, -1UL);
599}
600
601status_t ScreenshotClient::update(const sp<IBinder>& display,
602        uint32_t reqWidth, uint32_t reqHeight) {
603    sp<ISurfaceComposer> s(ComposerService::getComposerService());
604    if (s == NULL) return NO_INIT;
605    mHeap = 0;
606    return s->captureScreen(display, &mHeap,
607            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
608            0, -1UL);
609}
610
611status_t ScreenshotClient::update(const sp<IBinder>& display,
612        uint32_t reqWidth, uint32_t reqHeight,
613        uint32_t minLayerZ, uint32_t maxLayerZ) {
614    sp<ISurfaceComposer> s(ComposerService::getComposerService());
615    if (s == NULL) return NO_INIT;
616    mHeap = 0;
617    return s->captureScreen(display, &mHeap,
618            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
619            minLayerZ, maxLayerZ);
620}
621
622void ScreenshotClient::release() {
623    mHeap = 0;
624}
625
626void const* ScreenshotClient::getPixels() const {
627    return mHeap->getBase();
628}
629
630uint32_t ScreenshotClient::getWidth() const {
631    return mWidth;
632}
633
634uint32_t ScreenshotClient::getHeight() const {
635    return mHeight;
636}
637
638PixelFormat ScreenshotClient::getFormat() const {
639    return mFormat;
640}
641
642uint32_t ScreenshotClient::getStride() const {
643    return mWidth;
644}
645
646size_t ScreenshotClient::getSize() const {
647    return mHeap->getSize();
648}
649
650// ----------------------------------------------------------------------------
651}; // namespace android
652