blob: 699438c0d7177cdc04fa700b785c5f3141ac31e7 [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>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080020#include <sys/types.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080021
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080022#include <utils/Errors.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023#include <utils/Log.h>
Mathias Agopiand4784a32010-05-27 19:41:15 -070024#include <utils/Singleton.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070025#include <utils/SortedVector.h>
26#include <utils/String8.h>
27#include <utils/threads.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080028
Mathias Agopian9cce3252010-02-09 17:46:37 -080029#include <binder/IMemory.h>
Mathias Agopiana67932f2011-04-20 14:20:59 -070030#include <binder/IServiceManager.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080031
Mathias Agopian076b1cc2009-04-10 14:24:30 -070032#include <ui/DisplayInfo.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080033
Mathias Agopiana67932f2011-04-20 14:20:59 -070034#include <surfaceflinger/ISurface.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080035#include <surfaceflinger/ISurfaceComposer.h>
Mathias Agopian7e27f052010-05-28 14:22:23 -070036#include <surfaceflinger/ISurfaceComposerClient.h>
Mathias Agopian9cce3252010-02-09 17:46:37 -080037#include <surfaceflinger/SurfaceComposerClient.h>
38
39#include <private/surfaceflinger/LayerState.h>
40#include <private/surfaceflinger/SharedBufferStack.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080041
Mathias Agopian41f673c2011-11-17 17:48:35 -080042#include <private/gui/ComposerService.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080043
44namespace android {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080045// ---------------------------------------------------------------------------
46
Mathias Agopian7e27f052010-05-28 14:22:23 -070047ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
48
Mathias Agopianb7e930d2010-06-01 15:12:58 -070049ComposerService::ComposerService()
50: Singleton<ComposerService>() {
51 const String16 name("SurfaceFlinger");
52 while (getService(name, &mComposerService) != NO_ERROR) {
53 usleep(250000);
54 }
55 mServerCblkMemory = mComposerService->getCblk();
56 mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
57 mServerCblkMemory->getBase());
58}
59
60sp<ISurfaceComposer> ComposerService::getComposerService() {
61 return ComposerService::getInstance().mComposerService;
62}
63
64surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
65 return ComposerService::getInstance().mServerCblk;
66}
Mathias Agopian7e27f052010-05-28 14:22:23 -070067
68static inline sp<ISurfaceComposer> getComposerService() {
69 return ComposerService::getComposerService();
70}
71
72static inline surface_flinger_cblk_t const volatile * get_cblk() {
73 return ComposerService::getControlBlock();
74}
75
76// ---------------------------------------------------------------------------
77
Mathias Agopian698c0872011-06-28 19:09:31 -070078// NOTE: this is NOT a member function (it's a friend defined with its
79// declaration).
80static inline
81int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
82 if (lhs.client < rhs.client) return -1;
83 if (lhs.client > rhs.client) return 1;
84 if (lhs.state.surface < rhs.state.surface) return -1;
85 if (lhs.state.surface > rhs.state.surface) return 1;
86 return 0;
87}
88
Mathias Agopian7e27f052010-05-28 14:22:23 -070089class Composer : public Singleton<Composer>
90{
Mathias Agopiand4784a32010-05-27 19:41:15 -070091 friend class Singleton<Composer>;
92
Mathias Agopian698c0872011-06-28 19:09:31 -070093 mutable Mutex mLock;
94 SortedVector<ComposerState> mStates;
Jamie Gennisb8d69a52011-10-10 15:48:06 -070095 int mOrientation;
Jamie Gennis28378392011-10-12 17:39:00 -070096 uint32_t mForceSynchronous;
Mathias Agopian698c0872011-06-28 19:09:31 -070097
Jamie Gennisb8d69a52011-10-10 15:48:06 -070098 Composer() : Singleton<Composer>(),
Jamie Gennis28378392011-10-12 17:39:00 -070099 mOrientation(ISurfaceComposer::eOrientationUnchanged),
100 mForceSynchronous(0)
101 { }
Mathias Agopian698c0872011-06-28 19:09:31 -0700102
Jamie Gennis28378392011-10-12 17:39:00 -0700103 void closeGlobalTransactionImpl(bool synchronous);
Mathias Agopian698c0872011-06-28 19:09:31 -0700104
105 layer_state_t* getLayerStateLocked(
106 const sp<SurfaceComposerClient>& client, SurfaceID id);
107
Mathias Agopiand4784a32010-05-27 19:41:15 -0700108public:
Mathias Agopian698c0872011-06-28 19:09:31 -0700109
110 status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
Mathias Agopian41b6aab2011-08-30 18:51:54 -0700111 float x, float y);
Mathias Agopian698c0872011-06-28 19:09:31 -0700112 status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
113 uint32_t w, uint32_t h);
114 status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
115 int32_t z);
116 status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
117 uint32_t flags, uint32_t mask);
118 status_t setTransparentRegionHint(
119 const sp<SurfaceComposerClient>& client, SurfaceID id,
120 const Region& transparentRegion);
121 status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
122 float alpha);
123 status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
124 float dsdx, float dtdx, float dsdy, float dtdy);
125 status_t setFreezeTint(
126 const sp<SurfaceComposerClient>& client, SurfaceID id,
127 uint32_t tint);
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700128 status_t setOrientation(int orientation);
Mathias Agopian698c0872011-06-28 19:09:31 -0700129
Jamie Gennis28378392011-10-12 17:39:00 -0700130 static void closeGlobalTransaction(bool synchronous) {
131 Composer::getInstance().closeGlobalTransactionImpl(synchronous);
Mathias Agopiand4784a32010-05-27 19:41:15 -0700132 }
133};
134
135ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
136
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800137// ---------------------------------------------------------------------------
138
Jamie Gennis28378392011-10-12 17:39:00 -0700139void Composer::closeGlobalTransactionImpl(bool synchronous) {
Mathias Agopian698c0872011-06-28 19:09:31 -0700140 sp<ISurfaceComposer> sm(getComposerService());
141
142 Vector<ComposerState> transaction;
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700143 int orientation;
Jamie Gennis28378392011-10-12 17:39:00 -0700144 uint32_t flags = 0;
Mathias Agopian698c0872011-06-28 19:09:31 -0700145
146 { // scope for the lock
147 Mutex::Autolock _l(mLock);
148 transaction = mStates;
149 mStates.clear();
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700150
151 orientation = mOrientation;
152 mOrientation = ISurfaceComposer::eOrientationUnchanged;
Jamie Gennis28378392011-10-12 17:39:00 -0700153
154 if (synchronous || mForceSynchronous) {
155 flags |= ISurfaceComposer::eSynchronous;
156 }
157 mForceSynchronous = false;
Mathias Agopian698c0872011-06-28 19:09:31 -0700158 }
159
Jamie Gennis28378392011-10-12 17:39:00 -0700160 sm->setTransactionState(transaction, orientation, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800161}
162
Mathias Agopian698c0872011-06-28 19:09:31 -0700163layer_state_t* Composer::getLayerStateLocked(
164 const sp<SurfaceComposerClient>& client, SurfaceID id) {
165
166 ComposerState s;
167 s.client = client->mClient;
168 s.state.surface = id;
169
170 ssize_t index = mStates.indexOf(s);
171 if (index < 0) {
172 // we don't have it, add an initialized layer_state to our list
173 index = mStates.add(s);
174 }
175
176 ComposerState* const out = mStates.editArray();
177 return &(out[index].state);
178}
179
180status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
Mathias Agopian41b6aab2011-08-30 18:51:54 -0700181 SurfaceID id, float x, float y) {
Mathias Agopian698c0872011-06-28 19:09:31 -0700182 Mutex::Autolock _l(mLock);
183 layer_state_t* s = getLayerStateLocked(client, id);
184 if (!s)
185 return BAD_INDEX;
186 s->what |= ISurfaceComposer::ePositionChanged;
187 s->x = x;
188 s->y = y;
189 return NO_ERROR;
190}
191
192status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
193 SurfaceID id, uint32_t w, uint32_t h) {
194 Mutex::Autolock _l(mLock);
195 layer_state_t* s = getLayerStateLocked(client, id);
196 if (!s)
197 return BAD_INDEX;
198 s->what |= ISurfaceComposer::eSizeChanged;
199 s->w = w;
200 s->h = h;
Jamie Gennis28378392011-10-12 17:39:00 -0700201
202 // Resizing a surface makes the transaction synchronous.
203 mForceSynchronous = true;
204
Mathias Agopian698c0872011-06-28 19:09:31 -0700205 return NO_ERROR;
206}
207
208status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
209 SurfaceID id, int32_t z) {
210 Mutex::Autolock _l(mLock);
211 layer_state_t* s = getLayerStateLocked(client, id);
212 if (!s)
213 return BAD_INDEX;
214 s->what |= ISurfaceComposer::eLayerChanged;
215 s->z = z;
216 return NO_ERROR;
217}
218
219status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
220 SurfaceID id, uint32_t flags,
221 uint32_t mask) {
222 Mutex::Autolock _l(mLock);
223 layer_state_t* s = getLayerStateLocked(client, id);
224 if (!s)
225 return BAD_INDEX;
226 s->what |= ISurfaceComposer::eVisibilityChanged;
227 s->flags &= ~mask;
228 s->flags |= (flags & mask);
229 s->mask |= mask;
230 return NO_ERROR;
231}
232
233status_t Composer::setTransparentRegionHint(
234 const sp<SurfaceComposerClient>& client, SurfaceID id,
235 const Region& transparentRegion) {
236 Mutex::Autolock _l(mLock);
237 layer_state_t* s = getLayerStateLocked(client, id);
238 if (!s)
239 return BAD_INDEX;
240 s->what |= ISurfaceComposer::eTransparentRegionChanged;
241 s->transparentRegion = transparentRegion;
242 return NO_ERROR;
243}
244
245status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
246 SurfaceID id, float alpha) {
247 Mutex::Autolock _l(mLock);
248 layer_state_t* s = getLayerStateLocked(client, id);
249 if (!s)
250 return BAD_INDEX;
251 s->what |= ISurfaceComposer::eAlphaChanged;
252 s->alpha = alpha;
253 return NO_ERROR;
254}
255
256status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
257 SurfaceID id, float dsdx, float dtdx,
258 float dsdy, float dtdy) {
259 Mutex::Autolock _l(mLock);
260 layer_state_t* s = getLayerStateLocked(client, id);
261 if (!s)
262 return BAD_INDEX;
263 s->what |= ISurfaceComposer::eMatrixChanged;
264 layer_state_t::matrix22_t matrix;
265 matrix.dsdx = dsdx;
266 matrix.dtdx = dtdx;
267 matrix.dsdy = dsdy;
268 matrix.dtdy = dtdy;
269 s->matrix = matrix;
270 return NO_ERROR;
271}
272
273status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
274 SurfaceID id, uint32_t tint) {
275 Mutex::Autolock _l(mLock);
276 layer_state_t* s = getLayerStateLocked(client, id);
277 if (!s)
278 return BAD_INDEX;
279 s->what |= ISurfaceComposer::eFreezeTintChanged;
280 s->tint = tint;
281 return NO_ERROR;
282}
283
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700284status_t Composer::setOrientation(int orientation) {
285 Mutex::Autolock _l(mLock);
286 mOrientation = orientation;
Jamie Gennis28378392011-10-12 17:39:00 -0700287
288 // Changing the orientation makes the transaction synchronous.
289 mForceSynchronous = true;
290
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700291 return NO_ERROR;
292}
293
Mathias Agopian698c0872011-06-28 19:09:31 -0700294// ---------------------------------------------------------------------------
295
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800296SurfaceComposerClient::SurfaceComposerClient()
Mathias Agopian698c0872011-06-28 19:09:31 -0700297 : mStatus(NO_INIT), mComposer(Composer::getInstance())
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800298{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800299}
300
Mathias Agopian698c0872011-06-28 19:09:31 -0700301void SurfaceComposerClient::onFirstRef() {
Mathias Agopiand4784a32010-05-27 19:41:15 -0700302 sp<ISurfaceComposer> sm(getComposerService());
303 if (sm != 0) {
Mathias Agopian7e27f052010-05-28 14:22:23 -0700304 sp<ISurfaceComposerClient> conn = sm->createConnection();
Mathias Agopiand4784a32010-05-27 19:41:15 -0700305 if (conn != 0) {
306 mClient = conn;
Mathias Agopiand4784a32010-05-27 19:41:15 -0700307 mStatus = NO_ERROR;
308 }
309 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800310}
311
Mathias Agopian698c0872011-06-28 19:09:31 -0700312SurfaceComposerClient::~SurfaceComposerClient() {
Mathias Agopian631f3582010-05-25 17:51:34 -0700313 dispose();
314}
Mathias Agopiandd3423c2009-09-23 15:44:05 -0700315
Mathias Agopian698c0872011-06-28 19:09:31 -0700316status_t SurfaceComposerClient::initCheck() const {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800317 return mStatus;
318}
319
Mathias Agopian698c0872011-06-28 19:09:31 -0700320sp<IBinder> SurfaceComposerClient::connection() const {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800321 return (mClient != 0) ? mClient->asBinder() : 0;
322}
323
Mathias Agopiand4784a32010-05-27 19:41:15 -0700324status_t SurfaceComposerClient::linkToComposerDeath(
325 const sp<IBinder::DeathRecipient>& recipient,
Mathias Agopian698c0872011-06-28 19:09:31 -0700326 void* cookie, uint32_t flags) {
Mathias Agopiand4784a32010-05-27 19:41:15 -0700327 sp<ISurfaceComposer> sm(getComposerService());
328 return sm->asBinder()->linkToDeath(recipient, cookie, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800329}
330
Mathias Agopian698c0872011-06-28 19:09:31 -0700331void SurfaceComposerClient::dispose() {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800332 // this can be called more than once.
Mathias Agopian7e27f052010-05-28 14:22:23 -0700333 sp<ISurfaceComposerClient> client;
Mathias Agopiand4784a32010-05-27 19:41:15 -0700334 Mutex::Autolock _lm(mLock);
335 if (mClient != 0) {
Mathias Agopiand4784a32010-05-27 19:41:15 -0700336 client = mClient; // hold ref while lock is held
337 mClient.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800338 }
Mathias Agopiand4784a32010-05-27 19:41:15 -0700339 mStatus = NO_INIT;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800340}
341
Mathias Agopian698c0872011-06-28 19:09:31 -0700342sp<SurfaceControl> SurfaceComposerClient::createSurface(
343 DisplayID display,
344 uint32_t w,
345 uint32_t h,
346 PixelFormat format,
347 uint32_t flags)
348{
349 String8 name;
350 const size_t SIZE = 128;
351 char buffer[SIZE];
352 snprintf(buffer, SIZE, "<pid_%d>", getpid());
353 name.append(buffer);
354
355 return SurfaceComposerClient::createSurface(name, display,
356 w, h, format, flags);
357}
358
359sp<SurfaceControl> SurfaceComposerClient::createSurface(
360 const String8& name,
361 DisplayID display,
362 uint32_t w,
363 uint32_t h,
364 PixelFormat format,
365 uint32_t flags)
366{
367 sp<SurfaceControl> result;
368 if (mStatus == NO_ERROR) {
369 ISurfaceComposerClient::surface_data_t data;
370 sp<ISurface> surface = mClient->createSurface(&data, name,
371 display, w, h, format, flags);
372 if (surface != 0) {
Mathias Agopianc10d9d92011-07-20 16:46:11 -0700373 result = new SurfaceControl(this, surface, data);
Mathias Agopian698c0872011-06-28 19:09:31 -0700374 }
375 }
376 return result;
377}
378
379status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
380 if (mStatus != NO_ERROR)
381 return mStatus;
382 status_t err = mClient->destroySurface(sid);
383 return err;
384}
385
386inline Composer& SurfaceComposerClient::getComposer() {
387 return mComposer;
388}
389
390// ----------------------------------------------------------------------------
391
392void SurfaceComposerClient::openGlobalTransaction() {
393 // Currently a no-op
394}
395
Jamie Gennis28378392011-10-12 17:39:00 -0700396void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
397 Composer::closeGlobalTransaction(synchronous);
Mathias Agopian698c0872011-06-28 19:09:31 -0700398}
399
400// ----------------------------------------------------------------------------
401
402status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
403 return getComposer().setFreezeTint(this, id, tint);
404}
405
Mathias Agopian41b6aab2011-08-30 18:51:54 -0700406status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
Mathias Agopian698c0872011-06-28 19:09:31 -0700407 return getComposer().setPosition(this, id, x, y);
408}
409
410status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
411 return getComposer().setSize(this, id, w, h);
412}
413
414status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
415 return getComposer().setLayer(this, id, z);
416}
417
418status_t SurfaceComposerClient::hide(SurfaceID id) {
419 return getComposer().setFlags(this, id,
420 ISurfaceComposer::eLayerHidden,
421 ISurfaceComposer::eLayerHidden);
422}
423
424status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
425 return getComposer().setFlags(this, id,
426 0,
427 ISurfaceComposer::eLayerHidden);
428}
429
430status_t SurfaceComposerClient::freeze(SurfaceID id) {
431 return getComposer().setFlags(this, id,
432 ISurfaceComposer::eLayerFrozen,
433 ISurfaceComposer::eLayerFrozen);
434}
435
436status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
437 return getComposer().setFlags(this, id,
438 0,
439 ISurfaceComposer::eLayerFrozen);
440}
441
442status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
443 uint32_t mask) {
444 return getComposer().setFlags(this, id, flags, mask);
445}
446
447status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
448 const Region& transparentRegion) {
449 return getComposer().setTransparentRegionHint(this, id, transparentRegion);
450}
451
452status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
453 return getComposer().setAlpha(this, id, alpha);
454}
455
456status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
457 float dsdy, float dtdy) {
458 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
459}
460
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700461status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
462 int orientation, uint32_t flags)
463{
464 return Composer::getInstance().setOrientation(orientation);
465}
466
Mathias Agopian698c0872011-06-28 19:09:31 -0700467// ----------------------------------------------------------------------------
468
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800469status_t SurfaceComposerClient::getDisplayInfo(
470 DisplayID dpy, DisplayInfo* info)
471{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700472 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800473 return BAD_VALUE;
474
475 volatile surface_flinger_cblk_t const * cblk = get_cblk();
476 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
477
478 info->w = dcblk->w;
479 info->h = dcblk->h;
480 info->orientation = dcblk->orientation;
481 info->xdpi = dcblk->xdpi;
482 info->ydpi = dcblk->ydpi;
483 info->fps = dcblk->fps;
484 info->density = dcblk->density;
485 return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
486}
487
488ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
489{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700490 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800491 return BAD_VALUE;
492 volatile surface_flinger_cblk_t const * cblk = get_cblk();
493 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
494 return dcblk->w;
495}
496
497ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
498{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700499 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800500 return BAD_VALUE;
501 volatile surface_flinger_cblk_t const * cblk = get_cblk();
502 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
503 return dcblk->h;
504}
505
506ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
507{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700508 if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800509 return BAD_VALUE;
510 volatile surface_flinger_cblk_t const * cblk = get_cblk();
511 volatile display_cblk_t const * dcblk = cblk->displays + dpy;
512 return dcblk->orientation;
513}
514
515ssize_t SurfaceComposerClient::getNumberOfDisplays()
516{
517 volatile surface_flinger_cblk_t const * cblk = get_cblk();
518 uint32_t connected = cblk->connected;
519 int n = 0;
520 while (connected) {
521 if (connected&1) n++;
522 connected >>= 1;
523 }
524 return n;
525}
526
Mathias Agopian698c0872011-06-28 19:09:31 -0700527// ----------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800528
529status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
530{
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700531 // This has been made a no-op because it can cause Gralloc buffer deadlocks.
532 return NO_ERROR;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800533}
534
535status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
536{
Jamie Gennisb8d69a52011-10-10 15:48:06 -0700537 // This has been made a no-op because it can cause Gralloc buffer deadlocks.
538 return NO_ERROR;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800539}
540
Mathias Agopiand4784a32010-05-27 19:41:15 -0700541// ----------------------------------------------------------------------------
Mathias Agopian74c40c02010-09-29 13:02:36 -0700542
543ScreenshotClient::ScreenshotClient()
544 : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
545}
546
547status_t ScreenshotClient::update() {
548 sp<ISurfaceComposer> s(ComposerService::getComposerService());
549 if (s == NULL) return NO_INIT;
550 mHeap = 0;
551 return s->captureScreen(0, &mHeap,
Mathias Agopianbf2c6a62010-12-10 16:22:31 -0800552 &mWidth, &mHeight, &mFormat, 0, 0,
553 0, -1UL);
Mathias Agopian74c40c02010-09-29 13:02:36 -0700554}
555
556status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
557 sp<ISurfaceComposer> s(ComposerService::getComposerService());
558 if (s == NULL) return NO_INIT;
559 mHeap = 0;
560 return s->captureScreen(0, &mHeap,
Mathias Agopianbf2c6a62010-12-10 16:22:31 -0800561 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
562 0, -1UL);
563}
564
565status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
566 uint32_t minLayerZ, uint32_t maxLayerZ) {
567 sp<ISurfaceComposer> s(ComposerService::getComposerService());
568 if (s == NULL) return NO_INIT;
569 mHeap = 0;
570 return s->captureScreen(0, &mHeap,
571 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
572 minLayerZ, maxLayerZ);
Mathias Agopian74c40c02010-09-29 13:02:36 -0700573}
574
575void ScreenshotClient::release() {
576 mHeap = 0;
577}
578
579void const* ScreenshotClient::getPixels() const {
580 return mHeap->getBase();
581}
582
583uint32_t ScreenshotClient::getWidth() const {
584 return mWidth;
585}
586
587uint32_t ScreenshotClient::getHeight() const {
588 return mHeight;
589}
590
591PixelFormat ScreenshotClient::getFormat() const {
592 return mFormat;
593}
594
595uint32_t ScreenshotClient::getStride() const {
596 return mWidth;
597}
598
599size_t ScreenshotClient::getSize() const {
600 return mHeap->getSize();
601}
602
603// ----------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800604}; // namespace android