SurfaceComposerClient.cpp revision 28378392fd5aa3e0a392c9eb64634055678c3987
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 <surfaceflinger/ISurface.h>
35#include <surfaceflinger/ISurfaceComposer.h>
36#include <surfaceflinger/ISurfaceComposerClient.h>
37#include <surfaceflinger/SurfaceComposerClient.h>
38
39#include <private/surfaceflinger/LayerState.h>
40#include <private/surfaceflinger/SharedBufferStack.h>
41
42
43namespace android {
44// ---------------------------------------------------------------------------
45
46ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
47
48ComposerService::ComposerService()
49: Singleton<ComposerService>() {
50    const String16 name("SurfaceFlinger");
51    while (getService(name, &mComposerService) != NO_ERROR) {
52        usleep(250000);
53    }
54    mServerCblkMemory = mComposerService->getCblk();
55    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
56            mServerCblkMemory->getBase());
57}
58
59sp<ISurfaceComposer> ComposerService::getComposerService() {
60    return ComposerService::getInstance().mComposerService;
61}
62
63surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
64    return ComposerService::getInstance().mServerCblk;
65}
66
67static inline sp<ISurfaceComposer> getComposerService() {
68    return ComposerService::getComposerService();
69}
70
71static inline surface_flinger_cblk_t const volatile * get_cblk() {
72    return ComposerService::getControlBlock();
73}
74
75// ---------------------------------------------------------------------------
76
77// NOTE: this is NOT a member function (it's a friend defined with its
78// declaration).
79static inline
80int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
81    if (lhs.client < rhs.client)  return -1;
82    if (lhs.client > rhs.client)  return 1;
83    if (lhs.state.surface < rhs.state.surface)  return -1;
84    if (lhs.state.surface > rhs.state.surface)  return 1;
85    return 0;
86}
87
88class Composer : public Singleton<Composer>
89{
90    friend class Singleton<Composer>;
91
92    mutable Mutex               mLock;
93    SortedVector<ComposerState> mStates;
94    int                         mOrientation;
95    uint32_t                    mForceSynchronous;
96
97    Composer() : Singleton<Composer>(),
98        mOrientation(ISurfaceComposer::eOrientationUnchanged),
99        mForceSynchronous(0)
100    { }
101
102    void closeGlobalTransactionImpl(bool synchronous);
103
104    layer_state_t* getLayerStateLocked(
105            const sp<SurfaceComposerClient>& client, SurfaceID id);
106
107public:
108
109    status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
110            float x, float y);
111    status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
112            uint32_t w, uint32_t h);
113    status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
114            int32_t z);
115    status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
116            uint32_t flags, uint32_t mask);
117    status_t setTransparentRegionHint(
118            const sp<SurfaceComposerClient>& client, SurfaceID id,
119            const Region& transparentRegion);
120    status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
121            float alpha);
122    status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
123            float dsdx, float dtdx, float dsdy, float dtdy);
124    status_t setFreezeTint(
125            const sp<SurfaceComposerClient>& client, SurfaceID id,
126            uint32_t tint);
127    status_t setOrientation(int orientation);
128
129    static void closeGlobalTransaction(bool synchronous) {
130        Composer::getInstance().closeGlobalTransactionImpl(synchronous);
131    }
132};
133
134ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
135
136// ---------------------------------------------------------------------------
137
138void Composer::closeGlobalTransactionImpl(bool synchronous) {
139    sp<ISurfaceComposer> sm(getComposerService());
140
141    Vector<ComposerState> transaction;
142    int orientation;
143    uint32_t flags = 0;
144
145    { // scope for the lock
146        Mutex::Autolock _l(mLock);
147        transaction = mStates;
148        mStates.clear();
149
150        orientation = mOrientation;
151        mOrientation = ISurfaceComposer::eOrientationUnchanged;
152
153        if (synchronous || mForceSynchronous) {
154            flags |= ISurfaceComposer::eSynchronous;
155        }
156        mForceSynchronous = false;
157    }
158
159   sm->setTransactionState(transaction, orientation, flags);
160}
161
162layer_state_t* Composer::getLayerStateLocked(
163        const sp<SurfaceComposerClient>& client, SurfaceID id) {
164
165    ComposerState s;
166    s.client = client->mClient;
167    s.state.surface = id;
168
169    ssize_t index = mStates.indexOf(s);
170    if (index < 0) {
171        // we don't have it, add an initialized layer_state to our list
172        index = mStates.add(s);
173    }
174
175    ComposerState* const out = mStates.editArray();
176    return &(out[index].state);
177}
178
179status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
180        SurfaceID id, float x, float y) {
181    Mutex::Autolock _l(mLock);
182    layer_state_t* s = getLayerStateLocked(client, id);
183    if (!s)
184        return BAD_INDEX;
185    s->what |= ISurfaceComposer::ePositionChanged;
186    s->x = x;
187    s->y = y;
188    return NO_ERROR;
189}
190
191status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
192        SurfaceID id, uint32_t w, uint32_t h) {
193    Mutex::Autolock _l(mLock);
194    layer_state_t* s = getLayerStateLocked(client, id);
195    if (!s)
196        return BAD_INDEX;
197    s->what |= ISurfaceComposer::eSizeChanged;
198    s->w = w;
199    s->h = h;
200
201    // Resizing a surface makes the transaction synchronous.
202    mForceSynchronous = true;
203
204    return NO_ERROR;
205}
206
207status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
208        SurfaceID id, int32_t z) {
209    Mutex::Autolock _l(mLock);
210    layer_state_t* s = getLayerStateLocked(client, id);
211    if (!s)
212        return BAD_INDEX;
213    s->what |= ISurfaceComposer::eLayerChanged;
214    s->z = z;
215    return NO_ERROR;
216}
217
218status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
219        SurfaceID id, uint32_t flags,
220        uint32_t mask) {
221    Mutex::Autolock _l(mLock);
222    layer_state_t* s = getLayerStateLocked(client, id);
223    if (!s)
224        return BAD_INDEX;
225    s->what |= ISurfaceComposer::eVisibilityChanged;
226    s->flags &= ~mask;
227    s->flags |= (flags & mask);
228    s->mask |= mask;
229    return NO_ERROR;
230}
231
232status_t Composer::setTransparentRegionHint(
233        const sp<SurfaceComposerClient>& client, SurfaceID id,
234        const Region& transparentRegion) {
235    Mutex::Autolock _l(mLock);
236    layer_state_t* s = getLayerStateLocked(client, id);
237    if (!s)
238        return BAD_INDEX;
239    s->what |= ISurfaceComposer::eTransparentRegionChanged;
240    s->transparentRegion = transparentRegion;
241    return NO_ERROR;
242}
243
244status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
245        SurfaceID id, float alpha) {
246    Mutex::Autolock _l(mLock);
247    layer_state_t* s = getLayerStateLocked(client, id);
248    if (!s)
249        return BAD_INDEX;
250    s->what |= ISurfaceComposer::eAlphaChanged;
251    s->alpha = alpha;
252    return NO_ERROR;
253}
254
255status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
256        SurfaceID id, float dsdx, float dtdx,
257        float dsdy, float dtdy) {
258    Mutex::Autolock _l(mLock);
259    layer_state_t* s = getLayerStateLocked(client, id);
260    if (!s)
261        return BAD_INDEX;
262    s->what |= ISurfaceComposer::eMatrixChanged;
263    layer_state_t::matrix22_t matrix;
264    matrix.dsdx = dsdx;
265    matrix.dtdx = dtdx;
266    matrix.dsdy = dsdy;
267    matrix.dtdy = dtdy;
268    s->matrix = matrix;
269    return NO_ERROR;
270}
271
272status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
273        SurfaceID id, uint32_t tint) {
274    Mutex::Autolock _l(mLock);
275    layer_state_t* s = getLayerStateLocked(client, id);
276    if (!s)
277        return BAD_INDEX;
278    s->what |= ISurfaceComposer::eFreezeTintChanged;
279    s->tint = tint;
280    return NO_ERROR;
281}
282
283status_t Composer::setOrientation(int orientation) {
284    Mutex::Autolock _l(mLock);
285    mOrientation = orientation;
286
287    // Changing the orientation makes the transaction synchronous.
288    mForceSynchronous = true;
289
290    return NO_ERROR;
291}
292
293// ---------------------------------------------------------------------------
294
295SurfaceComposerClient::SurfaceComposerClient()
296    : mStatus(NO_INIT), mComposer(Composer::getInstance())
297{
298}
299
300void SurfaceComposerClient::onFirstRef() {
301    sp<ISurfaceComposer> sm(getComposerService());
302    if (sm != 0) {
303        sp<ISurfaceComposerClient> conn = sm->createConnection();
304        if (conn != 0) {
305            mClient = conn;
306            mStatus = NO_ERROR;
307        }
308    }
309}
310
311SurfaceComposerClient::~SurfaceComposerClient() {
312    dispose();
313}
314
315status_t SurfaceComposerClient::initCheck() const {
316    return mStatus;
317}
318
319sp<IBinder> SurfaceComposerClient::connection() const {
320    return (mClient != 0) ? mClient->asBinder() : 0;
321}
322
323status_t SurfaceComposerClient::linkToComposerDeath(
324        const sp<IBinder::DeathRecipient>& recipient,
325        void* cookie, uint32_t flags) {
326    sp<ISurfaceComposer> sm(getComposerService());
327    return sm->asBinder()->linkToDeath(recipient, cookie, flags);
328}
329
330void SurfaceComposerClient::dispose() {
331    // this can be called more than once.
332    sp<ISurfaceComposerClient> client;
333    Mutex::Autolock _lm(mLock);
334    if (mClient != 0) {
335        client = mClient; // hold ref while lock is held
336        mClient.clear();
337    }
338    mStatus = NO_INIT;
339}
340
341sp<SurfaceControl> SurfaceComposerClient::createSurface(
342        DisplayID display,
343        uint32_t w,
344        uint32_t h,
345        PixelFormat format,
346        uint32_t flags)
347{
348    String8 name;
349    const size_t SIZE = 128;
350    char buffer[SIZE];
351    snprintf(buffer, SIZE, "<pid_%d>", getpid());
352    name.append(buffer);
353
354    return SurfaceComposerClient::createSurface(name, display,
355            w, h, format, flags);
356}
357
358sp<SurfaceControl> SurfaceComposerClient::createSurface(
359        const String8& name,
360        DisplayID display,
361        uint32_t w,
362        uint32_t h,
363        PixelFormat format,
364        uint32_t flags)
365{
366    sp<SurfaceControl> result;
367    if (mStatus == NO_ERROR) {
368        ISurfaceComposerClient::surface_data_t data;
369        sp<ISurface> surface = mClient->createSurface(&data, name,
370                display, w, h, format, flags);
371        if (surface != 0) {
372            result = new SurfaceControl(this, surface, data);
373        }
374    }
375    return result;
376}
377
378status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
379    if (mStatus != NO_ERROR)
380        return mStatus;
381    status_t err = mClient->destroySurface(sid);
382    return err;
383}
384
385inline Composer& SurfaceComposerClient::getComposer() {
386    return mComposer;
387}
388
389// ----------------------------------------------------------------------------
390
391void SurfaceComposerClient::openGlobalTransaction() {
392    // Currently a no-op
393}
394
395void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
396    Composer::closeGlobalTransaction(synchronous);
397}
398
399// ----------------------------------------------------------------------------
400
401status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
402    return getComposer().setFreezeTint(this, id, tint);
403}
404
405status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
406    return getComposer().setPosition(this, id, x, y);
407}
408
409status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
410    return getComposer().setSize(this, id, w, h);
411}
412
413status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
414    return getComposer().setLayer(this, id, z);
415}
416
417status_t SurfaceComposerClient::hide(SurfaceID id) {
418    return getComposer().setFlags(this, id,
419            ISurfaceComposer::eLayerHidden,
420            ISurfaceComposer::eLayerHidden);
421}
422
423status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
424    return getComposer().setFlags(this, id,
425            0,
426            ISurfaceComposer::eLayerHidden);
427}
428
429status_t SurfaceComposerClient::freeze(SurfaceID id) {
430    return getComposer().setFlags(this, id,
431            ISurfaceComposer::eLayerFrozen,
432            ISurfaceComposer::eLayerFrozen);
433}
434
435status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
436    return getComposer().setFlags(this, id,
437            0,
438            ISurfaceComposer::eLayerFrozen);
439}
440
441status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
442        uint32_t mask) {
443    return getComposer().setFlags(this, id, flags, mask);
444}
445
446status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
447        const Region& transparentRegion) {
448    return getComposer().setTransparentRegionHint(this, id, transparentRegion);
449}
450
451status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
452    return getComposer().setAlpha(this, id, alpha);
453}
454
455status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
456        float dsdy, float dtdy) {
457    return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
458}
459
460status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
461        int orientation, uint32_t flags)
462{
463    return Composer::getInstance().setOrientation(orientation);
464}
465
466// ----------------------------------------------------------------------------
467
468status_t SurfaceComposerClient::getDisplayInfo(
469        DisplayID dpy, DisplayInfo* info)
470{
471    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
472        return BAD_VALUE;
473
474    volatile surface_flinger_cblk_t const * cblk = get_cblk();
475    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
476
477    info->w              = dcblk->w;
478    info->h              = dcblk->h;
479    info->orientation    = dcblk->orientation;
480    info->xdpi           = dcblk->xdpi;
481    info->ydpi           = dcblk->ydpi;
482    info->fps            = dcblk->fps;
483    info->density        = dcblk->density;
484    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
485}
486
487ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
488{
489    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
490        return BAD_VALUE;
491    volatile surface_flinger_cblk_t const * cblk = get_cblk();
492    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
493    return dcblk->w;
494}
495
496ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
497{
498    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
499        return BAD_VALUE;
500    volatile surface_flinger_cblk_t const * cblk = get_cblk();
501    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
502    return dcblk->h;
503}
504
505ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
506{
507    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
508        return BAD_VALUE;
509    volatile surface_flinger_cblk_t const * cblk = get_cblk();
510    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
511    return dcblk->orientation;
512}
513
514ssize_t SurfaceComposerClient::getNumberOfDisplays()
515{
516    volatile surface_flinger_cblk_t const * cblk = get_cblk();
517    uint32_t connected = cblk->connected;
518    int n = 0;
519    while (connected) {
520        if (connected&1) n++;
521        connected >>= 1;
522    }
523    return n;
524}
525
526// ----------------------------------------------------------------------------
527
528status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
529{
530    // This has been made a no-op because it can cause Gralloc buffer deadlocks.
531    return NO_ERROR;
532}
533
534status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
535{
536    // This has been made a no-op because it can cause Gralloc buffer deadlocks.
537    return NO_ERROR;
538}
539
540// ----------------------------------------------------------------------------
541
542ScreenshotClient::ScreenshotClient()
543    : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
544}
545
546status_t ScreenshotClient::update() {
547    sp<ISurfaceComposer> s(ComposerService::getComposerService());
548    if (s == NULL) return NO_INIT;
549    mHeap = 0;
550    return s->captureScreen(0, &mHeap,
551            &mWidth, &mHeight, &mFormat, 0, 0,
552            0, -1UL);
553}
554
555status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
556    sp<ISurfaceComposer> s(ComposerService::getComposerService());
557    if (s == NULL) return NO_INIT;
558    mHeap = 0;
559    return s->captureScreen(0, &mHeap,
560            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
561            0, -1UL);
562}
563
564status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
565        uint32_t minLayerZ, uint32_t maxLayerZ) {
566    sp<ISurfaceComposer> s(ComposerService::getComposerService());
567    if (s == NULL) return NO_INIT;
568    mHeap = 0;
569    return s->captureScreen(0, &mHeap,
570            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
571            minLayerZ, maxLayerZ);
572}
573
574void ScreenshotClient::release() {
575    mHeap = 0;
576}
577
578void const* ScreenshotClient::getPixels() const {
579    return mHeap->getBase();
580}
581
582uint32_t ScreenshotClient::getWidth() const {
583    return mWidth;
584}
585
586uint32_t ScreenshotClient::getHeight() const {
587    return mHeight;
588}
589
590PixelFormat ScreenshotClient::getFormat() const {
591    return mFormat;
592}
593
594uint32_t ScreenshotClient::getStride() const {
595    return mWidth;
596}
597
598size_t ScreenshotClient::getSize() const {
599    return mHeap->getSize();
600}
601
602// ----------------------------------------------------------------------------
603}; // namespace android
604