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