2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "SurfaceComposerClient"
20 #include <sys/types.h>
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>
29 #include <binder/IMemory.h>
30 #include <binder/IServiceManager.h>
32 #include <ui/DisplayInfo.h>
34 #include <gui/ISurface.h>
35 #include <gui/ISurfaceComposer.h>
36 #include <gui/ISurfaceComposerClient.h>
37 #include <gui/SurfaceComposerClient.h>
39 #include <private/gui/ComposerService.h>
40 #include <private/gui/LayerState.h>
41 #include <private/gui/SharedBufferStack.h>
44 // ---------------------------------------------------------------------------
46 ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
48 ComposerService::ComposerService()
49 : Singleton<ComposerService>() {
50 const String16 name("SurfaceFlinger");
51 while (getService(name, &mComposerService) != NO_ERROR) {
54 mServerCblkMemory = mComposerService->getCblk();
55 mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
56 mServerCblkMemory->getBase());
59 sp<ISurfaceComposer> ComposerService::getComposerService() {
60 return ComposerService::getInstance().mComposerService;
63 surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
64 return ComposerService::getInstance().mServerCblk;
67 static inline sp<ISurfaceComposer> getComposerService() {
68 return ComposerService::getComposerService();
71 static inline surface_flinger_cblk_t const volatile * get_cblk() {
72 return ComposerService::getControlBlock();
75 // ---------------------------------------------------------------------------
77 // NOTE: this is NOT a member function (it's a friend defined with its
80 int 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;
88 class Composer : public Singleton<Composer>
90 friend class Singleton<Composer>;
93 SortedVector<ComposerState> mStates;
95 uint32_t mForceSynchronous;
97 Composer() : Singleton<Composer>(),
98 mOrientation(ISurfaceComposer::eOrientationUnchanged),
102 void closeGlobalTransactionImpl(bool synchronous);
104 layer_state_t* getLayerStateLocked(
105 const sp<SurfaceComposerClient>& client, SurfaceID id);
109 status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
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,
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,
122 status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
123 float dsdx, float dtdx, float dsdy, float dtdy);
124 status_t setOrientation(int orientation);
125 status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id,
128 static void closeGlobalTransaction(bool synchronous) {
129 Composer::getInstance().closeGlobalTransactionImpl(synchronous);
133 ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
135 // ---------------------------------------------------------------------------
137 void Composer::closeGlobalTransactionImpl(bool synchronous) {
138 sp<ISurfaceComposer> sm(getComposerService());
140 Vector<ComposerState> transaction;
144 { // scope for the lock
145 Mutex::Autolock _l(mLock);
146 transaction = mStates;
149 orientation = mOrientation;
150 mOrientation = ISurfaceComposer::eOrientationUnchanged;
152 if (synchronous || mForceSynchronous) {
153 flags |= ISurfaceComposer::eSynchronous;
155 mForceSynchronous = false;
158 sm->setTransactionState(transaction, orientation, flags);
161 layer_state_t* Composer::getLayerStateLocked(
162 const sp<SurfaceComposerClient>& client, SurfaceID id) {
165 s.client = client->mClient;
166 s.state.surface = id;
168 ssize_t index = mStates.indexOf(s);
170 // we don't have it, add an initialized layer_state to our list
171 index = mStates.add(s);
174 ComposerState* const out = mStates.editArray();
175 return &(out[index].state);
178 status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
179 SurfaceID id, float x, float y) {
180 Mutex::Autolock _l(mLock);
181 layer_state_t* s = getLayerStateLocked(client, id);
184 s->what |= ISurfaceComposer::ePositionChanged;
190 status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
191 SurfaceID id, uint32_t w, uint32_t h) {
192 Mutex::Autolock _l(mLock);
193 layer_state_t* s = getLayerStateLocked(client, id);
196 s->what |= ISurfaceComposer::eSizeChanged;
200 // Resizing a surface makes the transaction synchronous.
201 mForceSynchronous = true;
206 status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
207 SurfaceID id, int32_t z) {
208 Mutex::Autolock _l(mLock);
209 layer_state_t* s = getLayerStateLocked(client, id);
212 s->what |= ISurfaceComposer::eLayerChanged;
217 status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
218 SurfaceID id, uint32_t flags,
220 Mutex::Autolock _l(mLock);
221 layer_state_t* s = getLayerStateLocked(client, id);
224 s->what |= ISurfaceComposer::eVisibilityChanged;
226 s->flags |= (flags & mask);
231 status_t Composer::setTransparentRegionHint(
232 const sp<SurfaceComposerClient>& client, SurfaceID id,
233 const Region& transparentRegion) {
234 Mutex::Autolock _l(mLock);
235 layer_state_t* s = getLayerStateLocked(client, id);
238 s->what |= ISurfaceComposer::eTransparentRegionChanged;
239 s->transparentRegion = transparentRegion;
243 status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
244 SurfaceID id, float alpha) {
245 Mutex::Autolock _l(mLock);
246 layer_state_t* s = getLayerStateLocked(client, id);
249 s->what |= ISurfaceComposer::eAlphaChanged;
254 status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
255 SurfaceID id, float dsdx, float dtdx,
256 float dsdy, float dtdy) {
257 Mutex::Autolock _l(mLock);
258 layer_state_t* s = getLayerStateLocked(client, id);
261 s->what |= ISurfaceComposer::eMatrixChanged;
262 layer_state_t::matrix22_t matrix;
271 status_t Composer::setOrientation(int orientation) {
272 Mutex::Autolock _l(mLock);
273 mOrientation = orientation;
275 // Changing the orientation makes the transaction synchronous.
276 mForceSynchronous = true;
281 status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
282 SurfaceID id, const Rect& crop) {
283 Mutex::Autolock _l(mLock);
284 layer_state_t* s = getLayerStateLocked(client, id);
287 s->what |= ISurfaceComposer::eCropChanged;
292 // ---------------------------------------------------------------------------
294 SurfaceComposerClient::SurfaceComposerClient()
295 : mStatus(NO_INIT), mComposer(Composer::getInstance())
299 void SurfaceComposerClient::onFirstRef() {
300 sp<ISurfaceComposer> sm(getComposerService());
302 sp<ISurfaceComposerClient> conn = sm->createConnection();
310 SurfaceComposerClient::~SurfaceComposerClient() {
314 status_t SurfaceComposerClient::initCheck() const {
318 sp<IBinder> SurfaceComposerClient::connection() const {
319 return (mClient != 0) ? mClient->asBinder() : 0;
322 status_t SurfaceComposerClient::linkToComposerDeath(
323 const sp<IBinder::DeathRecipient>& recipient,
324 void* cookie, uint32_t flags) {
325 sp<ISurfaceComposer> sm(getComposerService());
326 return sm->asBinder()->linkToDeath(recipient, cookie, flags);
329 void SurfaceComposerClient::dispose() {
330 // this can be called more than once.
331 sp<ISurfaceComposerClient> client;
332 Mutex::Autolock _lm(mLock);
334 client = mClient; // hold ref while lock is held
340 sp<SurfaceControl> SurfaceComposerClient::createSurface(
348 const size_t SIZE = 128;
350 snprintf(buffer, SIZE, "<pid_%d>", getpid());
353 return SurfaceComposerClient::createSurface(name, display,
354 w, h, format, flags);
357 sp<SurfaceControl> SurfaceComposerClient::createSurface(
365 sp<SurfaceControl> result;
366 if (mStatus == NO_ERROR) {
367 ISurfaceComposerClient::surface_data_t data;
368 sp<ISurface> surface = mClient->createSurface(&data, name,
369 display, w, h, format, flags);
371 result = new SurfaceControl(this, surface, data);
377 status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
378 if (mStatus != NO_ERROR)
380 status_t err = mClient->destroySurface(sid);
384 inline Composer& SurfaceComposerClient::getComposer() {
388 // ----------------------------------------------------------------------------
390 void SurfaceComposerClient::openGlobalTransaction() {
394 void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
395 Composer::closeGlobalTransaction(synchronous);
398 // ----------------------------------------------------------------------------
400 status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {
401 return getComposer().setCrop(this, id, crop);
404 status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
405 return getComposer().setPosition(this, id, x, y);
408 status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
409 return getComposer().setSize(this, id, w, h);
412 status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
413 return getComposer().setLayer(this, id, z);
416 status_t SurfaceComposerClient::hide(SurfaceID id) {
417 return getComposer().setFlags(this, id,
418 ISurfaceComposer::eLayerHidden,
419 ISurfaceComposer::eLayerHidden);
422 status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
423 return getComposer().setFlags(this, id,
425 ISurfaceComposer::eLayerHidden);
428 status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
430 return getComposer().setFlags(this, id, flags, mask);
433 status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
434 const Region& transparentRegion) {
435 return getComposer().setTransparentRegionHint(this, id, transparentRegion);
438 status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
439 return getComposer().setAlpha(this, id, alpha);
442 status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
443 float dsdy, float dtdy) {
444 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
447 status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
448 int orientation, uint32_t flags)
450 return Composer::getInstance().setOrientation(orientation);
453 // ----------------------------------------------------------------------------
455 status_t SurfaceComposerClient::getDisplayInfo(
456 DisplayID dpy, DisplayInfo* info)
458 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
461 volatile surface_flinger_cblk_t const * cblk = get_cblk();
462 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
466 info->orientation = dcblk->orientation;
467 info->xdpi = dcblk->xdpi;
468 info->ydpi = dcblk->ydpi;
469 info->fps = dcblk->fps;
470 info->density = dcblk->density;
471 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
474 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
476 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
478 volatile surface_flinger_cblk_t const * cblk = get_cblk();
479 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
483 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
485 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
487 volatile surface_flinger_cblk_t const * cblk = get_cblk();
488 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
492 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
494 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
496 volatile surface_flinger_cblk_t const * cblk = get_cblk();
497 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
498 return dcblk->orientation;
501 ssize_t SurfaceComposerClient::getNumberOfDisplays()
503 volatile surface_flinger_cblk_t const * cblk = get_cblk();
504 uint32_t connected = cblk->connected;
507 if (connected&1) n++;
513 // ----------------------------------------------------------------------------
515 ScreenshotClient::ScreenshotClient()
516 : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
519 status_t ScreenshotClient::update() {
520 sp<ISurfaceComposer> s(ComposerService::getComposerService());
521 if (s == NULL) return NO_INIT;
523 return s->captureScreen(0, &mHeap,
524 &mWidth, &mHeight, &mFormat, 0, 0,
528 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
529 sp<ISurfaceComposer> s(ComposerService::getComposerService());
530 if (s == NULL) return NO_INIT;
532 return s->captureScreen(0, &mHeap,
533 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
537 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
538 uint32_t minLayerZ, uint32_t maxLayerZ) {
539 sp<ISurfaceComposer> s(ComposerService::getComposerService());
540 if (s == NULL) return NO_INIT;
542 return s->captureScreen(0, &mHeap,
543 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
544 minLayerZ, maxLayerZ);
547 void ScreenshotClient::release() {
551 void const* ScreenshotClient::getPixels() const {
552 return mHeap->getBase();
555 uint32_t ScreenshotClient::getWidth() const {
559 uint32_t ScreenshotClient::getHeight() const {
563 PixelFormat ScreenshotClient::getFormat() const {
567 uint32_t ScreenshotClient::getStride() const {
571 size_t ScreenshotClient::getSize() const {
572 return mHeap->getSize();
575 // ----------------------------------------------------------------------------
576 }; // namespace android